zl程序教程

您现在的位置是:首页 >  Javascript

当前栏目

js浅拷贝与深拷贝

2023-02-25 18:27:41 时间

浅拷贝

只拷贝了基本类型数据和引用类型数据的指针,叫浅拷贝

被拷贝的对象里,如果没有引用类型的数据,可以使用浅拷贝,方便快捷。

如果有引用类型,那么存在被篡改的风险,更应该使用深拷贝

浅拷贝方法

1、手撸一个浅拷贝函数

1function shallowClone(obj) {
2    const newObj = {};
3    for(let prop in obj) {
4        if(obj.hasOwnProperty(prop)){
5            newObj[prop] = obj[prop];
6        }
7    }
8    return newObj;
9}
10

2、Object.assign / 展开运算符

1var obj = {
2    age: 18,
3    nature: ["smart", "good"],
4    names: {
5        name1: "fx",
6        name2: "xka"
7    },
8    love: function () {
9        console.log("fx is a great girl")
10    }
11}
12var newObj = Object.assign({}, fxObj);
13

3、数组的slice、concat方法

深拷贝

完全拷贝了基本类型和引用类型内部所有数据,叫深拷贝

深拷贝方法

1、JSON暴力转换

1const obj2=JSON.parse(JSON.stringify(obj1));

但是这种方式存在弊端,会忽略undefined、symbol、函数、正则。

1const obj = {
2    name: "A",
3    name1: undefined,
4    name2: /[a-zA-Z0-9]/g ,
5    name3: function() {},
6    name4:  Symbol("A")
7}
8const obj2 = JSON.parse(JSON.stringify(obj));
9console.log(obj2); // {name: "A"}

2、手撸深拷贝函数(循环+递归)

1function deepClone(obj, hash = new WeakMap()) {
2  if (obj === null) return obj; // 如果是null或者undefined我就不进行拷贝操作
3  if (obj instanceof Date) return new Date(obj);
4  if (obj instanceof RegExp) return new RegExp(obj);
5  // 可能是对象或者普通的值  如果是函数的话是不需要深拷贝
6  if (typeof obj !== "object") return obj;
7  // 是对象的话就要进行深拷贝
8  if (hash.get(obj)) return hash.get(obj);
9  let cloneObj = new obj.constructor();
10  // 找到的是所属类原型上的constructor,而原型上的 constructor指向的是当前类本身
11  hash.set(obj, cloneObj);
12  for (let key in obj) {
13    if (obj.hasOwnProperty(key)) {
14      // 实现一个递归拷贝
15      cloneObj[key] = deepClone(obj[key], hash);
16    }
17  }
18  return cloneObj;
19}
20