什么是最有效的方式来克隆一个JavaScript对象?我已经看到obj = eval(uneval(o));被使用,但它是非标准的,仅支持Firefox.我做了事情,如obj = JSON.parse(JSON.stringify(o));但质疑效率。
当前回答
有这么多方法可以实现这一点,但如果你想做到这一点没有任何图书馆,你可以使用以下方式:
const cloneObject = (oldObject) => {
let newObject = oldObject;
if (oldObject && typeof oldObject === 'object') {
if(Array.isArray(oldObject)) {
newObject = [];
} else if (Object.prototype.toString.call(oldObject) === '[object Date]' && !isNaN(oldObject)) {
newObject = new Date(oldObject.getTime());
} else {
newObject = {};
for (let i in oldObject) {
newObject[i] = cloneObject(oldObject[i]);
}
}
}
return newObject;
}
让我知道你在想什么。
其他回答
通过提出新的方法 Object.fromEntries(),它支持一些浏览器的更新的版本(参考)。
const obj = { key1: {key11: “key11”, key12: “key12”, key13: {key131: 22}}, key2: {key21: “key21”, key22: “key22”}, key3: “key3”, key4: [1,2,3, {key: “value”} } const cloneObj = (obj) => { if (Object(obj)!== obj) return obj; other if (Array.isArray(obj)) return obj.map(cloneObj); return Object.fromEntries(Object.entries(obj).map(([k,v])
如果您正在使用它,UnderScore.js图书馆有一个克隆方法。
var newObject = _.clone(oldObject);
克罗克福德建议(我更喜欢)使用此功能:
function object(o) {
function F() {}
F.prototype = o;
return new F();
}
var newObject = object(oldObject);
它是干净的,工作如预期,你不需要图书馆。
编辑:
这是一个对 Object.create 的聚合物,所以你也可以使用它。
var newObject = Object.create(oldObject);
注意: 如果你使用其中的一些,你可能有问题与某些 iteration谁使用 hasOwnProperty. 因为,创建创造新的空的对象,继承旧的对象. 但它仍然有用和实用的克隆对象。
例如,如果 oldObject.a = 5;
newObject.a; // is 5
但:
oldObject.hasOwnProperty(a); // is true
newObject.hasOwnProperty(a); // is false
对于清晰的旧的JavaScript对象,在现代运行时间中克隆对象的一种尝试和真正的好方法是简单的:
var clone = JSON.parse(JSON.stringify(obj));
现在,对于非清晰的JavaScript对象,没有一个真正简单的答案。 事实上,它不能因为JavaScript功能的动态性质和内部对象状态。 深度克隆一个JSON结构与内部功能需要你重建这些功能和它们的内部背景。
我们写了自己的,但我见过的最佳通用方法在这里覆盖:
首頁 〉外文書 〉文學 〉文學 〉 http://davidwalsh.name/javascript-clone
这是有效的吗? Heck 是的. 因为目标是产生一个真正的深复制克隆,那么你将不得不走路的成员的来源对象图。
所以你去吧!两个方法,我认为两者都是有效的。
扩展操作器... (原始序列 - 仅) 序列(0) (原始序列 - 仅) 序列() (原始序列 - 仅) concat() (原始序列 - 仅) 定制功能,如下所示(每个序列) jQuery 的 $.extend() (每个序列) JSON.parse(JSON.stringify()) (原始和字面序列 - 仅) Underscore 的 _.clone() (原始和字面序列 - 仅) Lodash 的 _.cloneDeep() (每个序列)
let arr1a = [1, 'a', true];
let arr1b = [...arr1a];
而且在哪裡 slice() 比 concat( 有更好的性能: https://jsbench.me/x5ktn7o94d/
let arr1c = arr1a.splice(0);
let arr1d = arr1a.slice();
let arr1e = arr1a.concat();
let arr2a = [1, 'a', true, {}, []];
let arr2b = JSON.parse(JSON.stringify(arr2a));
let arr3a = [1, 'a', true, {}, [], new Object()];
function copy(aObject) {
// Prevent undefined objects
// if (!aObject) return aObject;
let bObject = Array.isArray(aObject) ? [] : {};
let value;
for (const key in aObject) {
// Prevent self-references to parent object
// if (Object.is(aObject[key], aObject)) continue;
value = aObject[key];
bObject[key] = (typeof value === "object") ? copy(value) : value;
}
return bObject;
}
let arr3b = copy(arr3a);
或使用第三方实用功能:
let arr3c = $.extend(true, [], arr3a); // jQuery Extend
let arr3d = _.cloneDeep(arr3a); // Lodash
注意: jQuery 的 $.extend 也比 JSON.parse(JSON.stringify() 表现更好):