什么是最有效的方式来克隆一个JavaScript对象?我已经看到obj = eval(uneval(o));被使用,但它是非标准的,仅支持Firefox.我做了事情,如obj = JSON.parse(JSON.stringify(o));但质疑效率。
当前回答
希望这能帮助。
function deepClone(obj) {
/*
* Duplicates an object
*/
var ret = null;
if (obj !== Object(obj)) { // primitive types
return obj;
}
if (obj instanceof String || obj instanceof Number || obj instanceof Boolean) { // string objecs
ret = obj; // for ex: obj = new String("Spidergap")
} else if (obj instanceof Date) { // date
ret = new obj.constructor();
} else
ret = Object.create(obj.constructor.prototype);
var prop = null;
var allProps = Object.getOwnPropertyNames(obj); //gets non enumerables also
var props = {};
for (var i in allProps) {
prop = allProps[i];
props[prop] = false;
}
for (i in obj) {
props[i] = i;
}
//now props contain both enums and non enums
var propDescriptor = null;
var newPropVal = null; // value of the property in new object
for (i in props) {
prop = obj[i];
propDescriptor = Object.getOwnPropertyDescriptor(obj, i);
if (Array.isArray(prop)) { //not backward compatible
prop = prop.slice(); // to copy the array
} else
if (prop instanceof Date == true) {
prop = new prop.constructor();
} else
if (prop instanceof Object == true) {
if (prop instanceof Function == true) { // function
if (!Function.prototype.clone) {
Function.prototype.clone = function() {
var that = this;
var temp = function tmp() {
return that.apply(this, arguments);
};
for (var ky in this) {
temp[ky] = this[ky];
}
return temp;
}
}
prop = prop.clone();
} else // normal object
{
prop = deepClone(prop);
}
}
newPropVal = {
value: prop
};
if (propDescriptor) {
/*
* If property descriptors are there, they must be copied
*/
newPropVal.enumerable = propDescriptor.enumerable;
newPropVal.writable = propDescriptor.writable;
}
if (!ret.hasOwnProperty(i)) // when String or other predefined objects
Object.defineProperty(ret, i, newPropVal); // non enumerable
}
return ret;
}
HTTPS://github.com/jinujd/Javascript-Deep-Clone
其他回答
如果您正在使用它,UnderScore.js图书馆有一个克隆方法。
var newObject = _.clone(oldObject);
对于清晰的旧的JavaScript对象,在现代运行时间中克隆对象的一种尝试和真正的好方法是简单的:
var clone = JSON.parse(JSON.stringify(obj));
现在,对于非清晰的JavaScript对象,没有一个真正简单的答案。 事实上,它不能因为JavaScript功能的动态性质和内部对象状态。 深度克隆一个JSON结构与内部功能需要你重建这些功能和它们的内部背景。
我们写了自己的,但我见过的最佳通用方法在这里覆盖:
首頁 〉外文書 〉文學 〉文學 〉 http://davidwalsh.name/javascript-clone
这是有效的吗? Heck 是的. 因为目标是产生一个真正的深复制克隆,那么你将不得不走路的成员的来源对象图。
所以你去吧!两个方法,我认为两者都是有效的。
我通常使用 var newObj = JSON.parse( JSON.stringify(oldObje) );但是,这里有一个更合适的方式:
var o = {};
var oo = Object.create(o);
(o === oo); // => false
观看遗传浏览器!
Shallow copy one-lineer (ECMAScript 第五版):
var origin = { foo : {} };
var copy = Object.keys(origin).reduce(function(c,k){c[k]=origin[k];return c;},{});
console.log(origin, copy);
console.log(origin == copy); // false
console.log(origin.foo == copy.foo); // true
并下载单线复制(ECMAScript 第六版,2015年):
var origin = { foo : {} };
var copy = Object.assign({}, origin);
console.log(origin, copy);
console.log(origin == copy); // false
console.log(origin.foo == copy.foo); // true
克罗克福德建议(我更喜欢)使用此功能:
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
推荐文章
- 如何在禁用按钮上启用引导工具提示?
- Node.js全局变量
- 在前一个函数完成后调用另一个函数
- JavaScript中两个日期之间的月份差异
- 如何同时运行两个jQuery动画?
- 访问对象内存地址
- 如何将FormData (HTML5对象)转换为JSON
- Object.hasOwnProperty()产生ESLint 'no-prototype-builtins'错误:如何修复?
- 如何将Node.js流的内容读入字符串变量?
- 两个感叹号?
- 如何在JavaScript中计算今天之前三个月的日期?
- <script defer="defer">到底是如何工作的?
- 设置ajax超时
- 为什么JavaScript需要以“;”开头?
- 既然JavaScript和Java没有任何关系,它为什么被称为JavaScript ?