0%

js 深浅拷贝

浅拷贝

object.assign

扩展运算符

concat (数组)

sblice (数组)

深拷贝

JSON.stringfy()

手写递归实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
let obj1 = {
a: {
b: 1,
},
};

function deepClone(obj) {
let cloneObj = Array.isArray(obj) ? [] : {};

for (let key in obj) {
//遍历

if (typeof obj[key] === "object") {
cloneObj[key] = deepClone(obj[key]); //是对象就再次调用该函数递归
} else {
cloneObj[key] = obj[key]; //基本类型的话直接复制值
}
}

return cloneObj;
}

let obj2 = deepClone(obj1);

obj1.a.b = 2;

console.log(obj2); // {a:{b:1}}

改进后递归实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
const isComplexDataType = (obj) =>
(typeof obj === "object" || typeof obj === "function") && obj !== null;

const deepClone = function (obj, hash = new WeakMap()) {
if (obj.constructor === Date) return new Date(obj); // 日期对象直接返回一个新的日期对象

if (obj.constructor === RegExp) return new RegExp(obj); //正则对象直接返回一个新的正则对象

//如果循环引用了就用 weakMap 来解决

if (hash.has(obj)) return hash.get(obj);

let allDesc = Object.getOwnPropertyDescriptors(obj);

//遍历传入参数所有键的特性

let cloneObj = Object.create(Object.getPrototypeOf(obj), allDesc);

//继承原型链

hash.set(obj, cloneObj);

for (let key of Reflect.ownKeys(obj)) {
cloneObj[key] =
isComplexDataType(obj[key]) && typeof obj[key] !== "function"
? deepClone(obj[key], hash)
: obj[key];
}

return cloneObj;
};

// 下面是验证代码

let obj = {
num: 0,

str: "",

boolean: true,

unf: undefined,

nul: null,

obj: { name: "我是一个对象", id: 1 },

arr: [0, 1, 2],

func: function () {
console.log("我是一个函数");
},

date: new Date(0),

reg: new RegExp("/我是一个正则/ig"),

[Symbol("1")]: 1,
};

Object.defineProperty(obj, "innumerable", {
enumerable: false,
value: "不可枚举属性",
});

obj = Object.create(obj, Object.getOwnPropertyDescriptors(obj));

obj.loop = obj; // 设置loop成循环引用的属性

let cloneObj = deepClone(obj);

cloneObj.arr.push(4);

console.log("obj", obj);

console.log("cloneObj", cloneObj);

坚持技术分享,您的支持将鼓励我继续创作!

欢迎关注我的其它发布渠道