Object.create复制数组和对象属性的引用

时间:2015-12-02 17:34:57

标签: javascript arrays object

我试图了解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的数组和对象属性的引用?在启动新对象时不必创建新的数组和对象是非常好的。

1 个答案:

答案 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是克隆函数的名称

相关问题