什么是最有效的方式来克隆一个JavaScript对象?我已经看到obj = eval(uneval(o));被使用,但它是非标准的,仅支持Firefox.我做了事情,如obj = JSON.parse(JSON.stringify(o));但质疑效率。
当前回答
需要新的浏览器,但...
让我们扩展本地对象并获得一个真正的.extend();
Object.defineProperty(Object.prototype, 'extend', {
enumerable: false,
value: function(){
var that = this;
Array.prototype.slice.call(arguments).map(function(source){
var props = Object.getOwnPropertyNames(source),
i = 0, l = props.length,
prop;
for(; i < l; ++i){
prop = props[i];
if(that.hasOwnProperty(prop) && typeof(that[prop]) === 'object'){
that[prop] = that[prop].extend(source[prop]);
}else{
Object.defineProperty(that, prop, Object.getOwnPropertyDescriptor(source, prop));
}
}
});
return this;
}
});
只需在任何使用.extend() 对象的代码之前点击它。
例子:
var obj1 = {
node1: '1',
node2: '2',
node3: 3
};
var obj2 = {
node1: '4',
node2: 5,
node3: '6'
};
var obj3 = ({}).extend(obj1, obj2);
console.log(obj3);
// Object {node1: "4", node2: 5, node3: "6"}
其他回答
通过这个漫长的答案列表,几乎所有的解决方案都被覆盖了,除了我知道的一个。
JSON.parse(JSON.stringify( obj ); 通过 history.state 与 pushState 或 replaceState Web Notifications API 但这有缺点请求用户的许可。 通过对象进行自己的回归路径,以复制每个级别. 答案我没有看到 -> 使用 ServiceWorkers. 邮件(对象)在页面和 ServiceWorker 脚本之间返回和返回将是深的克隆
我使用npm克隆图书馆,显然它也在浏览器中工作。
https://www.npmjs.com/包装/克隆
let a = clone(b)
对于一个微小的副本,有一个很好的,简单的方法引入了ECMAScript2018标准,它涉及使用 Spread Operator :
let obj = {a : "foo", b:"bar" , c:10 , d:true , e:[1,2,3] };
let objClone = { ...obj };
我在Chrome浏览器中测试了它,两个对象都存储在不同的位置,所以即时更改儿童值在一个不会改变另一个。
这个技术是非常简单的,直前的,我认为这是一个真正的最佳实践这个问题一次和永远。
对象的克隆一直是JS的担忧,但在ES6之前,我列出了在下面的JavaScript中复制对象的不同方式,想象你有下面的对象,我希望有一个深刻的副本:
var obj = {a:1, b:2, c:3, d:4};
有几种方法可以复制这个对象,而不会改变其起源:
ES5+,使用一个简单的函数来为您进行复制:函数 deepCopyObj(obj) {如果(null == obj <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk> <unk>
希望这些帮助......
Object.assign({},sourceObj)只有在其属性没有参考类型密钥时才会克隆对象。
obj={a:"lol",b:["yes","no","maybe"]}
clonedObj = Object.assign({},obj);
clonedObj.b.push("skip")// changes will reflected to the actual obj as well because of its reference type.
obj.b //will also console => yes,no,maybe,skip
因此,对于深度克隆,不可能以这种方式实现。
最有效的解决方案是
var obj = Json.stringify(yourSourceObj)
var cloned = Json.parse(obj);