我有一个对象x。我想将其复制为对象y,这样对y的更改不会修改x。我意识到复制从内置JavaScript对象派生的对象会导致额外的、不需要的财产。这不是问题,因为我正在复制我自己的一个文字构造对象。

如何正确克隆JavaScript对象?


当前回答

我找到了一种用函数克隆对象的方法(打断多行以便于理解):

const clone = Object.assign(
    Object.create(
        Object.getPrototypeOf(originalObject)
    ),
    dataObject
);

其他回答

var x = {'e': 2, 'd': 8, 'b': 5};

const y = {};
for(let key in x) {
    y[key] = x[key];
}
console.log(y); // =>>> {e: 2, d: 8, b: 5}

const z = {};
Object.keys(x).forEach(key => {
    z[key] = x[key];
});
console.log(z); // =>>> {e: 2, d: 8, b: 5}

const w = {};
for(let i = 0; i < Object.keys(x).length; i++) {
    w[Object.keys(x)[i]] = x[Object.keys(x)[i]];
}
console.log(w); // =>>> {e: 2, d: 8, b: 5}

const v = {};
for(let key of Object.keys(x)) {
    v[key] = x[key];
}
console.log(v); // =>>> {e: 2, d: 8, b: 5}

x['q'] = 100;   // Altering x will not affect the other objects

console.log(x); // =>>> {e: 2, d: 8, b: 5, q: 100}
console.log(y); // =>>> {e: 2, d: 8, b: 5}
console.log(z); // =>>> {e: 2, d: 8, b: 5}
console.log(w); // =>>> {e: 2, d: 8, b: 5}
console.log(v); // =>>> {e: 2, d: 8, b: 5}
function clone(obj)
{
    var cloneObj = Object.create(obj);

    return cloneObj;
}

在Javascript中,对象单独继承另一个对象(原型继承)。create(obj)返回一个对象,该对象是obj的子对象或子对象。在上面的函数中,它将有效地返回该对象的副本。

然而,这是一种非常奇怪的克隆方式,因为我没有将继承用于其真正目的。

在一行代码中克隆Javascript对象的优雅方法

Object.assign方法是ECMAScript 2015(ES6)标准的一部分,它完全符合您的需要。

var clone = Object.assign({}, obj);

assign()方法用于将所有可枚举自身财产的值从一个或多个源对象复制到目标对象。

阅读更多。。。

支持旧浏览器的polyfill:

if (!Object.assign) {
  Object.defineProperty(Object, 'assign', {
    enumerable: false,
    configurable: true,
    writable: true,
    value: function(target) {
      'use strict';
      if (target === undefined || target === null) {
        throw new TypeError('Cannot convert first argument to object');
      }

      var to = Object(target);
      for (var i = 1; i < arguments.length; i++) {
        var nextSource = arguments[i];
        if (nextSource === undefined || nextSource === null) {
          continue;
        }
        nextSource = Object(nextSource);

        var keysArray = Object.keys(nextSource);
        for (var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex++) {
          var nextKey = keysArray[nextIndex];
          var desc = Object.getOwnPropertyDescriptor(nextSource, nextKey);
          if (desc !== undefined && desc.enumerable) {
            to[nextKey] = nextSource[nextKey];
          }
        }
      }
      return to;
    }
  });
}

根据Apple JavaScript编码指南:

// Create an inner object with a variable x whose default
// value is 3.
function innerObj()
{
        this.x = 3;
}
innerObj.prototype.clone = function() {
    var temp = new innerObj();
    for (myvar in this) {
        // this object does not contain any objects, so
        // use the lightweight copy code.
        temp[myvar] = this[myvar];
    }
    return temp;
}

// Create an outer object with a variable y whose default
// value is 77.
function outerObj()
{
        // The outer object contains an inner object.  Allocate it here.
        this.inner = new innerObj();
        this.y = 77;
}
outerObj.prototype.clone = function() {
    var temp = new outerObj();
    for (myvar in this) {
        if (this[myvar].clone) {
            // This variable contains an object with a
            // clone operator.  Call it to create a copy.
            temp[myvar] = this[myvar].clone();
        } else {
            // This variable contains a scalar value,
            // a string value, or an object with no
            // clone function.  Assign it directly.
            temp[myvar] = this[myvar];
        }
    }
    return temp;
}

// Allocate an outer object and assign non-default values to variables in
// both the outer and inner objects.
outer = new outerObj;
outer.inner.x = 4;
outer.y = 16;

// Clone the outer object (which, in turn, clones the inner object).
newouter = outer.clone();

// Verify that both values were copied.
alert('inner x is '+newouter.inner.x); // prints 4
alert('y is '+newouter.y); // prints 16

史蒂夫

使用jQuery,可以使用extend进行浅层复制:

var copiedObject = jQuery.extend({}, originalObject)

对copiedObject的后续更改不会影响originalObject,反之亦然。

或制作深度副本:

var copiedObject = jQuery.extend(true, {}, originalObject)