我试图了解Object.create在启动新对象时如何复制数组和对象属性。它似乎与复制字符串或数字不同。例如,如果我们有一个带有数字和数组属性的基本对象。 jsfiddle example
var obj = {
num: 0, arr: []
};
然后我们从这个基地发起3个新对象。
var set1 = Object.create(obj);
set1.num = 10;
set1.arr.push(1);
var set2 = Object.create(obj);
var set3 = Object.create(obj, {arr: []});
我期待set2.num和set2.arr属性成为它的初始状态。我发现这个数字是真的,但不是数组。当然,解决方法是在启动Object或创建重置arr属性的启动函数时传递{arr: []}
。
// false
console.log(set1.num === set2.num);
// true - why is this true???
console.log(set1.arr === set2.arr);
// false
console.log(set1.arr === set3.arr);
这是正常行为吗? Object.create是否保持对所有Object的数组和对象属性的引用?在启动新对象时不必创建新的数组和对象是非常好的。
答案 0 :(得分:1)
在启动新对象
时,不必创建新的数组和对象是非常好的
以您喜欢的风格编写一个功能
返回文字
function makeMyObject() {
return {num: 0, arr: []};
}
// usage
var obj = MyObject();
返回Object.create
d个对象,并assign
到它,
function makeMyObject() {
var o = Object.create(null); // or some prototype instead of `null`
return Object.assign(o, {num: 0, arr: []});
}
// usage
var obj = MyObject();
使用new
function MyObject() {
this.num = 0;
this.arr = [];
}
// usage
var obj = new MyObject();
克隆有点复杂,一个基本的例子可能是
function shallowClone(o) {
var e;
if (typeof o !== 'object')
return o;
e = Object.create(Object.getPrototypeOf(o));
// copy enumerable references
Object.assign(e, o);
// or to keep non-enumerable properties
// Object.defineProperties(b, Object.getOwnPropertyNames(o).map(Object.getOwnPropertyDescriptor.bind(Object, o)));
return e;
}
深度克隆需要循环遍历属性(例如for..in
仅可枚举)和类型检查,而不是简单地复制所有内容。您通常最终需要递归对象本身的属性。
对于已知类型,您也可以教它使用正确的构造函数,例如
if (Array.isArray(o)) {
e = [];
o.forEach((v, i) => e[i] = recurse(v));
}
其中recurse
是克隆函数的名称