Js深浅拷贝(理解)+深拷贝实现方法

深浅拷贝

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;
    }
  }
}

你可能感兴趣的:(javascript,前端,开发语言)