在node.js中克隆对象的最佳方法是什么
例:我想避免以下情况:
var obj1 = {x: 5, y:5};
var obj2 = obj1;
obj2.x = 6;
console.log(obj1.x); // logs 6
对象很可能包含复杂类型作为属性,所以简单的for(var x in obj1)解决不了问题。我需要自己写一个递归克隆吗?还是有一些我没有看到的内置的东西?
在node.js中克隆对象的最佳方法是什么
例:我想避免以下情况:
var obj1 = {x: 5, y:5};
var obj2 = obj1;
obj2.x = 6;
console.log(obj1.x); // logs 6
对象很可能包含复杂类型作为属性,所以简单的for(var x in obj1)解决不了问题。我需要自己写一个递归克隆吗?还是有一些我没有看到的内置的东西?
当前回答
在NodeJS中克隆Object的最简单和最快的方法是使用Object。Keys (obj)方法
var a = {"a": "a11", "b": "avc"};
var b;
for(var keys = Object.keys(a), l = keys.length; l; --l)
{
b[ keys[l-1] ] = a[ keys[l-1] ];
}
b.a = 0;
console.log("a: " + JSON.stringify(a)); // LOG: a: {"a":"a11","b":"avc"}
console.log("b: " + JSON.stringify(b)); // LOG: b: {"a":0,"b":"avc"}
方法Object。keys需要JavaScript 1.8.5;nodeJS v0.4.11支持此方法
当然对于嵌套对象需要实现递归func
另一个解决方案是使用原生JSON(在JavaScript 1.7中实现),但它比之前的要慢得多(大约慢10倍)
var a = {"a": i, "b": i*i};
var b = JSON.parse(JSON.stringify(a));
b.a = 0;
其他回答
Object.defineProperty(Object.prototype, "extend", {
enumerable: false,
value: function(from) {
var props = Object.getOwnPropertyNames(from);
var dest = this;
props.forEach(function(name) {
if (name in dest) {
var destination = Object.getOwnPropertyDescriptor(from, name);
Object.defineProperty(dest, name, destination);
}
});
return this;
}
});
这将定义一个您可以使用的扩展方法。代码来自本文。
我很惊讶,客体。还没有提到Assign。
let cloned = Object.assign({}, source);
如果可用(例如Babel),你可以使用对象展开操作符:
let cloned = { ... source };
如果你正在使用普通对象和数组,并且不关心克隆函数或递归引用,这里有一个简单的deepClone实现,它适用于普通对象、数组、字符串、数字、正则表达式、日期等。
// Simple Deep Clone
// Does not clone functions or handle recursive references.
function deepClone(original) {
if (original instanceof RegExp) {
return new RegExp(original);
} else if (original instanceof Date) {
return new Date(original.getTime());
} else if (Array.isArray(original)) {
return original.map(deepClone);
} else if (typeof original === 'object' && original !== null) {
const clone = {};
Object.keys(original).forEach(k => {
clone[k] = deepClone(original[k]);
});
return clone;
}
return original;
}
// Usage:
const obj = { n: 1, a: [ { a: 1 }, { a: 2 } ], d: new Date(), s: 'foo' };
const clone = deepClone(obj);
在寻找一个真正的克隆选项时,我偶然发现了一个可笑的链接:
http://my.opera.com/GreyWyvern/blog/show.dml/1725165
我修改了该页上的解决方案,以便附加到Object原型的函数是不可枚举的。这是我的结果:
Object.defineProperty(Object.prototype, 'clone', {
enumerable: false,
value: function() {
var newObj = (this instanceof Array) ? [] : {};
for (i in this) {
if (i == 'clone') continue;
if (this[i] && typeof this[i] == "object") {
newObj[i] = this[i].clone();
} else newObj[i] = this[i]
} return newObj;
}
});
希望这也能帮助到其他人。注意,这里有一些注意事项……特别是对于名为“clone”的属性。这对我来说很有效。这不是我写的。同样,我只是改变了它的定义方式。
如果你正在使用coffee-script,它就像:
newObject = {}
newObject[key] = value for own key,value of oldObject
虽然这不是一个深度克隆。