什么是最有效的方式来克隆一个JavaScript对象?我已经看到obj = eval(uneval(o));被使用,但它是非标准的,仅支持Firefox.我做了事情,如obj = JSON.parse(JSON.stringify(o));但质疑效率。
当前回答
Lodash 有一个可爱的 _.cloneDeep(值) 方法:
var objects = [{ 'a': 1 }, { 'b': 2 }];
var deep = _.cloneDeep(objects);
console.log(deep[0] === objects[0]);
// => false
其他回答
需要新的浏览器,但...
让我们扩展本地对象并获得一个真正的.extend();
Object.defineProperty(Object.prototype, 'extend', {
enumerable: false,
value: function(){
var that = this;
Array.prototype.slice.call(arguments).map(function(source){
var props = Object.getOwnPropertyNames(source),
i = 0, l = props.length,
prop;
for(; i < l; ++i){
prop = props[i];
if(that.hasOwnProperty(prop) && typeof(that[prop]) === 'object'){
that[prop] = that[prop].extend(source[prop]);
}else{
Object.defineProperty(that, prop, Object.getOwnPropertyDescriptor(source, prop));
}
}
});
return this;
}
});
只需在任何使用.extend() 对象的代码之前点击它。
例子:
var obj1 = {
node1: '1',
node2: '2',
node3: 3
};
var obj2 = {
node1: '4',
node2: 5,
node3: '6'
};
var obj3 = ({}).extend(obj1, obj2);
console.log(obj3);
// Object {node1: "4", node2: 5, node3: "6"}
有很多答案,但没有一个给了我需要的效果,我想利用jQuery的深复制的力量......但是,当它进入一个序列时,它只是复制了对序列的参考,并深复制了其中内容。
(它甚至检查 kendo.data.ObservableArray 如果你想要它! 但是, 确保你打电话 kendo.observable(newItem) 如果你想 Arrays 再次可观察。
所以,要完全复制一个现有项目,你只是这样做:
var newItem = jQuery.extend(true, {}, oldItem);
createNewArrays(newItem);
function createNewArrays(obj) {
for (var prop in obj) {
if ((kendo != null && obj[prop] instanceof kendo.data.ObservableArray) || obj[prop] instanceof Array) {
var copy = [];
$.each(obj[prop], function (i, item) {
var newChild = $.extend(true, {}, item);
createNewArrays(newChild);
copy.push(newChild);
});
obj[prop] = copy;
}
}
}
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))
是最慢的方式来深化一个对象(它比 jQuery.extend 更慢,深旗定为 10-20% )。
jQuery.extend 是相当快的,当深旗被设置为虚假(shallow clone)。这是一个很好的选择,因为它包含一些额外的逻辑的类型验证,并且不复制未定义的属性,等等,但这也将放缓你下一点。
如果你知道你正在试图克隆的对象的结构,或者可以避免深深的<unk>,你可以写一个简单的为(var i in obj) loop 克隆你的对象,同时检查 hasOwnProperty 它会比 jQuery 快得多。
var clonedObject = {
knownProp: obj.knownProp,
..
}
更新 ES6
Object.assign({}, obj);
假设您只拥有属性,而不是对象中的任何功能,您只能使用:
var newObject = JSON.parse(JSON.stringify(oldObject));
推荐文章
- 给一个数字加上st, nd, rd和th(序数)后缀
- 如何以编程方式触发引导模式?
- setTimeout带引号和不带括号的区别
- 在JS的Chrome CPU配置文件中,'self'和'total'之间的差异
- 用javascript检查输入字符串中是否包含数字
- 如何使用JavaScript分割逗号分隔字符串?
- 在Javascript中~~(“双波浪号”)做什么?
- 谷歌chrome扩展::console.log()从后台页面?
- 未捕获的SyntaxError:
- [].slice的解释。调用javascript?
- jQuery日期/时间选择器
- 合并两个PHP对象的最佳方法是什么?
- 我如何预填充一个jQuery Datepicker文本框与今天的日期?
- 数组的indexOf函数和findIndex函数的区别
- jQuery添加必要的输入字段