什么是最有效的方式来克隆一个JavaScript对象?我已经看到obj = eval(uneval(o));被使用,但它是非标准的,仅支持Firefox.我做了事情,如obj = JSON.parse(JSON.stringify(o));但质疑效率。


当前回答

structuredClone(value)

如有必要,先加载聚合物:

import structuredClone from '@ungap/structured-clone';

查看此答案更多详细信息

如果您不使用日期、功能、未定义、无限、RegExps、地图、集、博布、文件列表、图像数据、分布式列表、类型列表或其它复杂类型在您的对象中,那么一个非常简单的单一列表来深化对象是:

JSON.parse(JSON.stringify(对象) )

lodash - cloneDeep; 可以通过 lodash.clonedeep 模块单独进口,并且可能是您最好的选择,如果您已经不使用图书馆,提供深度克隆功能 AngularJS - angular.copy jQuery - jQuery.extend(真实, { }, oldObject);.clone() 只克隆 DOM 元素仅图书馆 - just-clone; 一部分图书馆的零依赖 npm 模块,只做一件事。

其他回答

通过这个漫长的答案列表,几乎所有的解决方案都被覆盖了,除了我知道的一个。

JSON.parse(JSON.stringify( obj ); 通过 history.state 与 pushState 或 replaceState Web Notifications API 但这有缺点请求用户的许可。 通过对象进行自己的回归路径,以复制每个级别. 答案我没有看到 -> 使用 ServiceWorkers. 邮件(对象)在页面和 ServiceWorker 脚本之间返回和返回将是深的克隆

由于这个问题有很多注意力和答案,参考内置的功能,如 Object.assign 或自定义代码到深克隆,我想分享一些图书馆到深克隆,

1、斯克隆

npm 安装 --savedev esclone https://www.npmjs.com/package/esclone

在 ES6 中使用例子:

import esclone from "esclone";

const rockysGrandFather = {
  name: "Rockys grand father",
  father: "Don't know :("
};
const rockysFather = {
  name: "Rockys Father",
  father: rockysGrandFather
};

const rocky = {
  name: "Rocky",
  father: rockysFather
};

const rockyClone = esclone(rocky);

在 ES5 中使用例子:

var esclone = require("esclone")
var foo = new String("abcd")
var fooClone = esclone.default(foo)
console.log(fooClone)
console.log(foo === fooClone)

二、深度复制

npm 安装深复制 https://www.npmjs.com/package/deep-copy

例子:

var dcopy = require('deep-copy')

// deep copy object 
var copy = dcopy({a: {b: [{c: 5}]}})

// deep copy array 
var copy = dcopy([1, 2, {a: {b: 5}}])

3、克隆深度

$ npm 安装 --save clone-deep https://www.npmjs.com/package/clone-deep

例子:

var cloneDeep = require('clone-deep');

var obj = {a: 'b'};
var arr = [obj];

var copy = cloneDeep(arr);
obj.c = 'd';

console.log(copy);
//=> [{a: 'b'}] 

console.log(arr);

只是因为我没有看到AngularJS提到并认为人们可能想知道......

angular.copy 还提供深复制对象和序列的方法。

对于未来的参考,可以使用此代码

第6章:

_clone: function(obj){
    let newObj = {};
    for(let i in obj){
        if(typeof(obj[i]) === 'object' && Object.keys(obj[i]).length){
            newObj[i] = clone(obj[i]);
        } else{
            newObj[i] = obj[i];
        }
    }
    return Object.assign({},newObj);
}

第5章:

function clone(obj){
let newObj = {};
for(let i in obj){
    if(typeof(obj[i]) === 'object' && Object.keys(obj[i]).length){
        newObj[i] = clone(obj[i]);
    } else{
        newObj[i] = obj[i];
    }
}
return Object.assign({},newObj);

) )

E.G

var obj ={a:{b:1,c:3},d:4,e:{f:6}}
var xc = clone(obj);
console.log(obj); //{a:{b:1,c:3},d:4,e:{f:6}}
console.log(xc); //{a:{b:1,c:3},d:4,e:{f:6}}

xc.a.b = 90;
console.log(obj); //{a:{b:1,c:3},d:4,e:{f:6}}
console.log(xc); //{a:{b:90,c:3},d:4,e:{f:6}}

Lodash 有一个功能,以便你这样做。

var foo = {a: 'a', b: {c:'d', e: {f: 'g'}}};

var bar = _.cloneDeep(foo);
// bar = {a: 'a', b: {c:'d', e: {f: 'g'}}} 

阅读这里的DOC。