什么是最有效的方式来克隆一个JavaScript对象?我已经看到obj = eval(uneval(o));被使用,但它是非标准的,仅支持Firefox.我做了事情,如obj = JSON.parse(JSON.stringify(o));但质疑效率。
当前回答
对于一个微小的副本,有一个很好的,简单的方法引入了ECMAScript2018标准,它涉及使用 Spread Operator :
let obj = {a : "foo", b:"bar" , c:10 , d:true , e:[1,2,3] };
let objClone = { ...obj };
我在Chrome浏览器中测试了它,两个对象都存储在不同的位置,所以即时更改儿童值在一个不会改变另一个。
这个技术是非常简单的,直前的,我认为这是一个真正的最佳实践这个问题一次和永远。
其他回答
如何在一行代码中克隆(而不是深克隆)对象
Object.assign 方法是 ECMAScript 2015 (ES6) 标准的一部分,并且正是您所需要的。
var clone = Object.assign({}, obj);
使用 Object.assign() 方法将所有可列的属性从一个或多个源对象的值复制到目标对象。
阅读更多...
支持老年浏览器的多元化:
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;
}
});
}
克罗克福德建议(我更喜欢)使用此功能:
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
function clone(obj)
{ var clone = {};
clone.prototype = obj.prototype;
for (property in obj) clone[property] = obj[property];
return clone;
}
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 模块,只做一件事。
如果沒有任何內建一個,你可以嘗試:
function clone(obj) {
if (obj === null || typeof (obj) !== 'object' || 'isActiveClone' in obj)
return obj;
if (obj instanceof Date)
var temp = new obj.constructor(); //or new Date(obj);
else
var temp = obj.constructor();
for (var key in obj) {
if (Object.prototype.hasOwnProperty.call(obj, key)) {
obj['isActiveClone'] = null;
temp[key] = clone(obj[key]);
delete obj['isActiveClone'];
}
}
return temp;
}
推荐文章
- 转换php数组到Javascript
- 如何跳转到浏览器页面的顶部
- 在电子邮件消息中是否支持JavaScript ?
- 如何在JavaScript中指定Math.log()的基?
- 多重左赋值JavaScript
- 如何在单个测试基础上更改模拟实现?
- VueJS有条件地为元素添加属性
- Uncaught TypeError:(中间值)(…)不是一个函数
- 如何设置URL查询参数在Vue与Vue路由器
- 无法读取属性“addEventListener”为空
- 如何防止moment.js从webpack加载地区?
- getMonth在javascript中给出前一个月
- 如何在禁用按钮上启用引导工具提示?
- Node.js全局变量
- 在前一个函数完成后调用另一个函数