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

本文详细解释了JavaScript中深拷贝和浅拷贝的概念及其实现方法,包括使用JSON转换、普通递归函数以及防栈溢出函数进行深拷贝的具体步骤,并分析了各种方法的优缺点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

深浅拷贝

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;
    }
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值