Javascript 实现深拷贝有几种方式

  1. 对于基本类型比如字符串、数字等默认赋值就是深拷贝。
  2. 对于引用类型,比如对象、数组,默认赋值是浅拷贝,即改变一个变量值,另一个也会改变,它们的深拷贝有两种情况:
    • 被更改对象、数组只有一层:
    	let a = [1, 2, 3];
    	let aa = [...a];
    	a[0] = 99;
    	console.log(a, aa);
    
    	let b = {test: 1, ok: 2};
    	let bb = {...b};
    	// 或者 let bb = Object.assign({}, b)
    	b.ok = 3;
    	console.log(b, bb);
    
    • 被更改对象、数组超过一层
      • 元素只有基本类型,可以使用JSON.stringify/parse
      // 被更改部分处于第二层,Object.assign无法深拷贝
      let b = {test: {a: 22}, ok: 2};
      let bb = Object.assign({}, b)
      b.test.a = 3;
      console.log(b, bb);
      // 被更改部分处于第一层,Object.assign可以深拷贝
      bb = Object.assign({}, b)
      b.ok = 3;
      console.log(b, bb);
      // 使用JSON字符串解析实现深拷贝
      let bbb = JSON.parse(JSON.stringify(b));
      b.test.a = 4;
      console.log(b, bbb);
      
      • 元素包含方法等类型,使用通用深拷贝方法。

通用深拷贝方法

function deepCopy(target) {
	let newTarget = null;
	if (Object.prototype.toString.call(target) !== "[object Array]" && Object.prototype.toString.call(target) !== "[object Object]") {
		return target;
	}
	 newTarget = Array.isArray(target) ? [] : {};
	 if (Object.prototype.toString.call(target) === "[object Array]") {
	 	for (const data of target) {
			newTarget.push(deepCopy(data));
		}
	 } else {
	 	for (const key of Object.keys(target)) {
			newTarget[key] = deepCopy(target[key]);
		}
	 }
	return newTarget;
	}

使用:let a = {test: 1}; let aa = deepCopy(a);

标签: 深拷贝, javascript

添加新评论

0%