深浅拷贝
let a = 1;
let b = a ;
a = 10;
console.log(a,b); // 结果为a:10 , b:1
此时你会发现a,b的结果不一样,但等号赋值是浅拷贝;
通过assign方法可实现枚举复制 也可达到浅拷贝的效果
而引用类型,是在堆内存中 开辟一块空间,而这块空间的地址会赋值给变量,当两个地址指向一个存储空间时会更改同一个地址下的东西,这就是浅拷贝;
实现深拷贝的方法
JSON转换
var target = JSON.parse(JSON.stringify(obj)) //objj为你要深拷贝的对象
//target 为你拷贝好的对象
1.JSON方法缺点
(1)如果对象里有函数,函数无法被拷贝下来
(2)无法拷贝copyObj对象原型链上的属性和方法
(3)当数据的层次很深,会栈溢出
2.普通递归函数
function deepCopy( source ) {
if (!isObject(source)) return source; //如果不是对象的话直接返回
let target = Array.isArray( source ) ? [] : {} //数组兼容
for ( var k in source ) {
if (source.hasOwnProperty(k)) {
if ( typeof source[ k ] === 'object' ) {
target[ k ] = deepCopy( source[ k ] )
} else {
target[ k ] = source[ k ]
}
}
}
return target
}
function isObject(obj) {
return typeof obj === 'object' && obj !== null
}
普通递归函数缺点:
(1)无法保持引用
(2)当数据的层次很深,会栈溢出
3.防栈溢出函数
function cloneLoop(x) {
const root = {};
// 栈
const loopList = [
{
parent: root,
key: undefined,
data: x,
}
];
while(loopList.length) {
// 深度优先
const node = loopList.pop();
const parent = node.parent;
const key = node.key;
const data = node.data;
// 初始化赋值目标,key为undefined则拷贝到父元素,否则拷贝到子元素
let res = parent;
if (typeof key !== 'undefined') {
res = parent[key] = {};
}
for(let k in data) {
if (data.hasOwnProperty(k)) {
if (typeof data[k] === 'object') {
// 下一次循环
loopList.push({
parent: res,
key: k,
data: data[k],
});
} else {
res[k] = data[k];
}
}
}
}
return root;
}
防栈溢出函数优点:
(1)不会栈溢出
(2)支持很多层级的数据
递归方式深拷贝
function depCopy(target, source) {
for (let i in source) {
let sourceValue = source[i]
if (sourceValue instanceof Object) {
let subTarget = new sourceValue.constructor
target[i] = subTarget
depCopy(subTarget, sourceValue)
} else {
target[i] = sourceValue;
}
}
}