JS之深浅拷贝

1. 技巧性深浅拷贝

1.1 数组的浅拷贝

数组,我们可以利用数组的一些方法比如:sliceconcat 返回一个新数组的特性来实现拷贝。

let arr = ['old', 1, true, null, undefined, { old: "old" }];

let new_arr = arr.concat();

//var new_arr = arr.slice();

new_arr[0] = 'new';

arr[5].old = "new";

console.log(arr) // ["old", 1, true, null, undefined, {old: 'new'}]
console.log(new_arr) // ["new", 1, true, null, undefined, {old: 'new'}]

新数组和旧数组都发生了变化,也就是说使用 concat 或 slice 方法,克隆的并不彻底。

如果数组元素是基本类型,就会拷贝一份,互不影响,而如果是对象或者数组,就会只拷贝对象和数组的引用,这样我们无论在新旧数组进行了修改,两者都会发生变化。

这种复制引用的拷贝方法称之为浅拷贝,与之对应的就是深拷贝,深拷贝就是指完全的拷贝一个对象,即使嵌套了对象,两者也相互分离,修改一个对象的属性,也不会影响另一个。

1.2 数组的深拷贝

使用 JSON 的 parse 和 stringify 进行深拷贝。同样适用于对象。

var arr = ['old', 1, true, ['old1', 'old2'], { old: 1 }, function () { console.log("fun"); }]

var new_arr = JSON.parse(JSON.stringify(arr));

console.log(arr);
console.log(new_arr);

问题:new_arr 中 第五项数组元素为 null ,不能拷贝函数。

2. 对象/数组 拷贝

2.1 浅拷贝

function shallowCopy(object) {
  if (!object || typeof object !== "object") return;

  let obj = Array.isArray(object) ? [] : {};

  for (let key in object) {
    if (object.hasOwnProperty(key)) {
      obj[key] = object[key];
    }
  }
  return obj;
}

2.2 深拷贝

function deepCopy(object) {
  if (!object || typeof object !== "object") return object;

  let obj = Array.isArray(object) ? [] : {};

  for (let key in object) {
    if (object.hasOwnProperty(key)) {
      obj[key] = deepCopy(object[key]);
    }
  }
  return obj;
}
posted @ 2021-09-25 22:37  青柠i  阅读(47)  评论(0编辑  收藏  举报