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中数据内存空间示意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;
由上图可以看出,基本数据类型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 }
网友评论