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


当前回答

如果你正在使用普通对象和数组,并且不关心克隆函数或递归引用,这里有一个简单的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);

其他回答

我很惊讶,客体。还没有提到Assign。

let cloned = Object.assign({}, source);

如果可用(例如Babel),你可以使用对象展开操作符:

let cloned = { ... source };

在寻找一个真正的克隆选项时,我偶然发现了一个可笑的链接:

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”的属性。这对我来说很有效。这不是我写的。同样,我只是改变了它的定义方式。

如果你不想“滚出你自己的”,还有一些Node模块。这个看起来不错:https://www.npmjs.com/package/clone

看起来它可以处理各种各样的东西,包括循环引用。来自github页面:

clone主人克隆对象,数组,日期对象和RegEx 对象。所有内容都是递归克隆的,因此您可以克隆日期 例如,在对象的数组中。[…循环推荐?是的!

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

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

希望这对你有帮助。

这段代码也是object .create()方法使用指定的原型对象和属性创建一个新对象的原因。

var obj1 = {x:5, y:5};

var obj2 = Object.create(obj1);

obj2.x; //5
obj2.x = 6;
obj2.x; //6

obj1.x; //5