function
deepClone(
initalObj,
finalObj) {
var
obj =
finalObj || {};
for (
var
i
in
initalObj) {
if (
typeof
initalObj[
i] ===
'object') {
obj[
i] = (
initalObj[
i].
constructor ===
Array) ? [] : {};
arguments.
callee(
initalObj[
i],
obj[
i]);
}
else {
obj[
i] =
initalObj[
i];
}
}
return
obj;
}
var
str = {};
var
obj = {
a: {
a:
"hello",
b:
21} };
deepClone(
obj,
str);
console.log(str.a);
上述代码确实可以实现深拷贝。但是当遇到两个互相引用的对象,会出现死循环的情况。
为了避免相互引用的对象导致死循环的情况,则应该在遍历的时候判断是否相互引用对象,如果是则退出循环。
改进版代码如下:
function deepClone(initalObj, finalObj) { var obj = finalObj || {}; for (var i in initalObj) { var prop = initalObj[i]; // 避免相互引用对象导致死循环,如initalObj.a = initalObj的情况 if(prop === obj) { continue; } if (typeof prop === 'object') { obj[i] = (prop.constructor === Array) ? [] : {}; arguments.callee(prop, obj[i]); } else { obj[i] = prop; } } return obj; } var str = {}; var obj = { a: {a: "hello", b: 21} }; deepClone(obj, str); console.log(str.a);
使用Object.create()方法
直接使用var newObj = Object.create(oldObj),可以达到深拷贝的效果。
function deepClone(initalObj, finalObj) { var obj = finalObj || {}; for (var i in initalObj) { var prop = initalObj[i]; // 避免相互引用对象导致死循环,如initalObj.a = initalObj的情况 if(prop === obj) { continue; } if (typeof prop === 'object') { obj[i] = (prop.constructor === Array) ? [] : Object.create(prop); } else { obj[i] = prop; } } return obj; }jquery
jquery 有提供一个
$.extend
可以用来做 Deep Copy。var $ = require('jquery'); var obj1 = { a: 1, b: { f: { g: 1 } }, c: [1, 2, 3] }; var obj2 = $.extend(true, {}, obj1); console.log(obj1.b.f === obj2.b.f); // falselodash
另外一个很热门的函数库lodash,也有提供
_.cloneDeep
用来做 Deep Copy。var _ = require('lodash'); var obj1 = { a: 1, b: { f: { g: 1 } }, c: [1, 2, 3] }; var obj2 = _.cloneDeep(obj1); console.log(obj1.b.f === obj2.b.f); // false这个性能还不错,使用起来也很简单。