深拷贝&浅拷贝
1、区别
浅拷贝:只拷贝了基本数据类型,引用数据类型只复制了引用,没有复制实体。
深拷贝:拷贝所有的层级属性
2、浅拷贝
(1) 直接赋值
拷贝之后,所有层级属性仍然公用了地址,会被影响
var a = [0, 1, [2,3], 4], b = a; a[0] = 1; a[2][0] = 1; console.log(a); // [1,1,[1,3],4] console.log(b); // [1,1,[1,3],4]
(2) slice 返回指定元素
第一层的属性确实深拷贝,拥有了独立的内存,但更深的属性却仍然公用了地址
var a = [0, 1, [2,3], 4], b = a.slice(); a[0] = 1; a[2][0] = 1; console.log(a); // [1,1,[1,3],4] console.log(b); // [0,1,[1,3],4]
(3) contact 连接2个和多个数组
第一层的属性确实深拷贝,拥有了独立的内存,但更深的属性却仍然公用了地址
var a = [0, 1, [2,3], 4], var b = a.concat(4,5); a[0] = 1; a[2][0] = 1; console.log(a); // [1,1,[1,3],4] console.log(b); // [0,1,[1,3],4,5]
(4) object.assign 合并多个对象
第一层的属性确实深拷贝,拥有了独立的内存,但更深的属性却仍然公用了地址
var a = [0, 1, [2,3], 4], b = Object.assign([], a); a[0] = 1; a[2][0] = 1; console.log(a); // [1,1,[1,3],4] console.log(b); // [0,1,[1,3],4]
(5) 对象扩展运算符 === Object.assign
第一层的属性确实深拷贝,拥有了独立的内存,但更深的属性却仍然公用了地址
var a = [0, 1, [2,3], 4], b = [...a]; a[0] = 1; a[2][0] = 1; console.log(a); // [1,1,[1,3],4] console.log(b); // [0,1,[1,3],4]
3、深拷贝
(1) JSON方法(只能拷贝简单对象,对象里面包含函数无法拷贝)
JSON.parse(JSON.stringify(obj))
(2) for循环递归实现
(3) jquery可以$.extend(true, {}, obj)
(4)第三方函数lodash的_.cloneDeep