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

如何正确克隆JavaScript对象?


当前回答

您可以简单地使用扩展属性来复制没有引用的对象。但是要小心(请参见注释),“副本”仅位于最低的对象/数组级别。嵌套的财产仍然是引用!


完整克隆:

let x = {a: 'value1'}
let x2 = {...x}

// => mutate without references:

x2.a = 'value2'
console.log(x.a)    // => 'value1'

在第二级克隆引用:

const y = {a: {b: 'value3'}}
const y2 = {...y}

// => nested object is still a references:

y2.a.b = 'value4'
console.log(y.a.b)    // => 'value4'

JavaScript实际上不支持本地深度克隆。使用效用函数。例如Ramda:

http://ramdajs.com/docs/#clone

其他回答

您可以简单地使用扩展属性来复制没有引用的对象。但是要小心(请参见注释),“副本”仅位于最低的对象/数组级别。嵌套的财产仍然是引用!


完整克隆:

let x = {a: 'value1'}
let x2 = {...x}

// => mutate without references:

x2.a = 'value2'
console.log(x.a)    // => 'value1'

在第二级克隆引用:

const y = {a: {b: 'value3'}}
const y2 = {...y}

// => nested object is still a references:

y2.a.b = 'value4'
console.log(y.a.b)    // => 'value4'

JavaScript实际上不支持本地深度克隆。使用效用函数。例如Ramda:

http://ramdajs.com/docs/#clone

const objClone = { ...obj };

请注意,嵌套对象仍作为引用复制。

根据Airbnb JavaScript风格指南,有404位贡献者:

首选对象排列运算符而不是对象。指定为浅层复制物体。使用object rest操作符获取具有特定省略了财产。

// very bad
const original = { a: 1, b: 2 };
const copy = Object.assign(original, { c: 3 }); // this mutates `original` ಠ_ಠ
delete copy.a; // so does this

// bad
const original = { a: 1, b: 2 };
const copy = Object.assign({}, original, { c: 3 }); // copy => { a: 1, b: 2, c: 3 }

// good
const original = { a: 1, b: 2 };
const copy = { ...original, c: 3 }; // copy => { a: 1, b: 2, c: 3 }

const { a, ...noA } = copy; // noA => { b: 2, c: 3 }

此外,我想提醒您,尽管Airbnb几乎不建议使用对象扩散运算符方法。请记住,Microsoft Edge仍然不支持此2018功能。

ES2016+公司表>>

function clone(obj) {
    if(obj == null || typeof(obj) != 'object')
        return obj;    
    var temp = new obj.constructor(); 
    for(var key in obj)
        temp[key] = clone(obj[key]);    
    return temp;
}

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

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

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

或制作深度副本:

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