在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)解决不了问题。我需要自己写一个递归克隆吗?还是有一些我没有看到的内置的东西?
当前回答
可能性1
低装饰深度复制:
var obj2 = JSON.parse(JSON.stringify(obj1));
可能性2(已弃用)
注意:这个解决方案现在在Node.js的文档中被标记为已弃用:
util._extend()方法从未打算在内部Node.js模块之外使用。社区发现并使用了它。 它已弃用,不应在新代码中使用。JavaScript通过Object.assign()提供了非常类似的内置功能。
原来的答案::
对于浅拷贝,使用Node内置的util._extend()函数。
var extend = require('util')._extend;
var obj1 = {x: 5, y:5};
var obj2 = extend({}, obj1);
obj2.x = 6;
console.log(obj1.x); // still logs 5
Node的_extend函数的源代码在这里:https://github.com/joyent/node/blob/master/lib/util.js
exports._extend = function(origin, add) {
// Don't do anything if add isn't an object
if (!add || typeof add !== 'object') return origin;
var keys = Object.keys(add);
var i = keys.length;
while (i--) {
origin[keys[i]] = add[keys[i]];
}
return origin;
};
其他回答
如果你正在使用普通对象和数组,并且不关心克隆函数或递归引用,这里有一个简单的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”的属性。这对我来说很有效。这不是我写的。同样,我只是改变了它的定义方式。
还有另一个库lodash,它有clone和cloneDeep。
Clone将克隆您的对象,但不会为非原语值创建一个新实例,而是使用对原始对象的引用
cloneDeep将在不引用原始对象的情况下创建新的对象,因此当您随后必须更改对象时更安全。
查看underscore.js。它具有克隆和扩展以及许多其他非常有用的功能。
这可能很有用:在Node.js中使用下划线模块
如果你不想“滚出你自己的”,还有一些Node模块。这个看起来不错:https://www.npmjs.com/package/clone
看起来它可以处理各种各样的东西,包括循环引用。来自github页面:
clone主人克隆对象,数组,日期对象和RegEx 对象。所有内容都是递归克隆的,因此您可以克隆日期 例如,在对象的数组中。[…循环推荐?是的!