正如其他人在这里所说:第一个分配,为现有对象分配一个新引用,第二个执行浅复制。
我的意思是浅 : 只会复制基础对象,没有递归:
var a = {some:'propery',
another:{might:'be',
an: 'object, too'}
};
var b = {};
for(var p in a)
{
b[p] = a[p];
}
b.some = 'b\'s own property';
console.log(a.some);//property -> unaltered
console.log(b.some);//b's own property --> separate entities
b.another.might = 'foo';
console.log(a.another.might);//foo ==> b.another references a.another
要解决这个问题,你会认为一个简单的递归函数就足够了:
var cloneObj = function(o)
{
var p,r = {};
for (p in o)
{//omitting checks for functions, date objects and the like
r[p] = (o[p] instanceof Object ? cloneObj(o[p]) : o[p]);
}
};
但要厌倦循环引用!
//assume a is the same object as above
a._myself = a;//<- a references itself
这将产生无休止的递归,也就是死锁场景,除非您针对这种情况添加检查:
var cloneObj = function(o)
{
var p,r = {};
for (p in o)
{//Needs a lot more work, just a basic example of a recursive copy function
switch(true)
{
case o[p] instanceof Function:
r[p] = o[p];
break;
case o[p] instanceof Date:
r[p] = new Date(o[p]);
break;
case o === o[p]:
//simple circular references only
//a.some.child.object.references = a; will still cause trouble
r[p] = r;
break;
case o[p] instanceof Array:
r[p] = o[p].slice(0);//copy arrays
break;
default:
r[p] = o[p] instanceof Object ? cloneObj(o[p]) : o[p];
}
}
return r;
};
现在,这很冗长,而且在大多数情况下完全是多余的,如果您想要的是两个具有相同数据但可以独立更改的对象(即不要在内存中引用相同的对象),那么您只需要是 1 行代码:
var a = {some:'propery',
another:{might:'be',
an: 'object, too'}
};
var b = JSON.parse(JSON.stringify(a));
底线:分配引用肯定更有效:它不需要第二次调用对象构造函数,也不需要任何常量的额外副本。
缺点是:您最终会得到一个对象,并且可能会无意中更改/删除您认为在使用其他参考时仍然存在的东西 (delete b.some;/*some time later*/a.some.replace(/p/g,'q');//<--error)