在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)解决不了问题。我需要自己写一个递归克隆吗?还是有一些我没有看到的内置的东西?


当前回答

var obj2 = JSON.parse(JSON.stringify(obj1));

其他回答

在Github上也有一个项目,旨在成为jQuery.extend()的更直接的端口:

https://github.com/dreamerslab/node.extend

下面是一个例子,来自jQuery文档:

var extend = require('node.extend');

var object1 = {
    apple: 0,
    banana: {
        weight: 52,
        price: 100
    },
    cherry: 97
};

var object2 = {
    banana: {
        price: 200
    },
    durian: 100
};

var merged = extend(object1, object2);

可能性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;
};

如果你正在使用coffee-script,它就像:

newObject = {}
newObject[key] = value  for own key,value of oldObject

虽然这不是一个深度克隆。

你可以原型对象,然后调用对象实例,每次你想使用和改变对象:

function object () {
  this.x = 5;
  this.y = 5;
}
var obj1 = new object();
var obj2 = new object();
obj2.x = 6;
console.log(obj1.x); //logs 5

也可以将参数传递给对象构造函数

function object (x, y) {
   this.x = x;
   this.y = y;
}
var obj1 = new object(5, 5);
var obj2 = new object(6, 6);
console.log(obj1.x); //logs 5
console.log(obj2.x); //logs 6

希望这对你有帮助。

还有另一个库lodash,它有clone和cloneDeep。

Clone将克隆您的对象,但不会为非原语值创建一个新实例,而是使用对原始对象的引用

cloneDeep将在不引用原始对象的情况下创建新的对象,因此当您随后必须更改对象时更安全。