1. 深拷贝 和 浅拷贝
浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存。
深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象。
1.1. 实现浅拷贝
var obj1 = { a: 10, b: 20, c: 30 };
var obj2 = obj1;
obj2.b = 100;
console.log(obj1);
// { a: 10, b: 100, c: 30 } <-- b 被改到了
console.log(obj2);
// { a: 10, b: 100, c: 30 }
1.2. 实现深拷贝
method 1: 手动复制方式
var obj1 = { a: 10, b: 20, c: 30 };
var obj2 = { a: obj1.a, b: obj1.b, c: obj1.c };
obj2.b = 100;
console.log(obj1);
// { a: 10, b: 20, c: 30 } <-- b 沒被改到
console.log(obj2);
// { a: 10, b: 100, c: 30 }
method 2: Object.assign, { ...obj }
obj1 = { a: 10, b: 20, c: 30 };
obj2 = Object.assign({}, obj1); // { ...obj1 }
obj2.b = 100;
console.log(obj1);
// { a: 10, b: 20, c: 30 } <-- 沒被改到
console.log(obj2);
// { a: 10, b: 100, c: 30 }
但是对于深层嵌套的 obj,不能实现深拷贝,深层 obj 仍然是引用关系。
method 3: 转成 JSON 再转回来
用 JSON.stringify
把对象转成字符串,再用 JSON.parse
把字符串转成新的对象。
缺点:只有可以转成 JSON 格式的对象才可以这样用,像 function 没办法转成 JSON。
method 4: 第三方
- jquery,有提供一个
$.extend
可以用来做 Deep Copy。 - lodash,也有提供
_.cloneDeep
用来做 Deep Copy。
method 5: 递归实现深拷贝
easy version:
- create an empty obj which will be returned as a new object
- loop thru each property of original object
- if the value for a property is not object, assign it to new obj
- else if property is object, recursively call deepClone
function deepClone(o) {
var temp = {};
for (var k in o) {
if (typeof o[k] == 'object') {
temp[k] = deepClone(o[k]);
} else {
temp[k] = o[k];
}
}
return temp;
}
complex version: please search common.js -- deepClone