js基础:(1)js内存空间、深度拷贝

1 预备知识


1.1 对计算机内存机制有一定的理解,知道堆和栈的概念。


  • (操作系统): 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收,分配方式类似于链表。
    堆则是存放在二级缓存中,生命周期由虚拟机的垃圾回收算法来决定(并不是一旦成为孤儿对象就能被回收)。所以调用这些对象的速度要相对来得低一些。

  • (操作系统):由操作系统自动分配释放 ,存放函数的局部变量的值等。其操作方式类似于数据结构中的栈。
    栈使用的是一级缓存, 他们通常都是被调用时处于存储空间中,调用完毕立即释放。

1.2 对js的数据类型有一定了解。

  • 基本数据类型 Undefined, Null, Boolean, Number和String.
  • 复杂数据类型Object.

基本数据类型例如
var a1=0;
a1作为变量名,0作为变量具体值,在栈中以简单数据段存储。

Object类型

var b=[1,2,3]; var c={ m:12, n:‘w’ };

b、c作为变量名,在栈内存中以简单数据段存储,并存储其对应具体对象内容的地址即指针。

其存储关系如下图所示:

js基础:(1)js内存空间、深度拷贝_第1张图片
js中数据内存空间示意

2 js拷贝问题

在实际应用中常见的问题出在,需要多处使用对象引用值的时候。如下示例:

let a1,a2,a3; a1=[1,2,3]; a2=a1; a3=a1; a3[1]=0;

虽然只是a3作了修改,但实际上a1,a2,a3的值都将变为[1,0,3]。
此时应使用深拷贝

2.1 浅拷贝-即变量赋值

结合1.2节的例子,

var a1=0; var s=a1; var b=[1,2,3]; var p=b;

js基础:(1)js内存空间、深度拷贝_第2张图片
基本数据类型和对象引用浅拷贝示意

由上图可以看出,基本数据类型s会在占内存中分配一个空间,存入变量与对应的值。而对象则是在栈中开辟一个空间,复制的是对象的指针,实际对象的内容对应的是同一个。所以一旦改动p,b的数据值也会被改变。

2.2 深拷贝基本实现

思路:递归调用浅拷贝

typeof()函数-判断数据类型

`
typeof(true) //boolean
typeof(1) //number
typeof(1) //string
typeof({}) //object
typeof([]) //object

typeof(null) //object
typeof(function(){}) //function
“str23”.constructor === String
“str23”.constructor .name==="string"
[].constructor === Array
`

深拷贝实现js代码(主要针对数组和对象形式的

function deepCopy(p, c) {     var c = c || ((p.constructor === Array) ? [] : {});    for (var i in p) {       if (typeof p[i] === 'object') {         c[i] = (p[i].constructor === Array) ? [] : {};         deepCopy(p[i], c[i]);       } else {          c[i] = p[i];       }     }     return c;   } var a = [1, 2, 3]; var a2 = { xx: [1, 2, 3], yy: 2 }; var b = []; var c = deepCopy(a2); console.log(deepCopy(a), c); //运行结果[ 1, 2, 3 ] { xx: [ 1, 2, 3 ], yy: 2 }

你可能感兴趣的:(js基础:(1)js内存空间、深度拷贝)