深拷贝

来源:互联网 发布:淘宝会员账号怎么注册 编辑:程序博客网 时间:2024/05/01 18:58
function deepClone(initalObj, finalObj) {
var obj = finalObj || {};
for (vari in initalObj) {
if (typeofinitalObj[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);// false

lodash

另外一个很热门的函数库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

这个性能还不错,使用起来也很简单。