原型继承和实例数组的问题

时间:2010-07-28 14:56:46

标签: javascript inheritance prototype node.js

我使用原型继承,并希望拥有带有实例数组的对象。因此,如果我从一个具有实例数组的对象派生一些对象并访问该数组,则所有这些对象都共享该数组。我想把一些东西推到数组中,只改变实际对象中的数组,而不是所有其他对象。

使用标准原型继承和Object.create对这个问题有什么优势解决方案?

var sys = require('sys');

var obj ={
    data: [],
    add: function(what){
        this.data.push(what)
    }
};

var one = Object.create(obj);
one.add(1);

var other = Object.create(obj);
other.add(2);

sys.puts(other.data.length); // is 2, but should be 1

4 个答案:

答案 0 :(得分:2)

var ObjectName = function(){
    this.data = [];
}

ObjectName.prototype.add = function(what){
    this.data.push(what);
};

var one = new ObjectName();
one.add(1);

答案 1 :(得分:1)

Object.create没有优雅的解决方案,因为你做错了。

你想要的是:

function MyArray() {
    this.data = [];  // per-instance data here
}

MyArray.prototype = {
    add: function(what) {  // prototype methods here
        this.data.push(what);
    }
};

var one = new MyArray;
one.add(1);
...

答案 2 :(得分:0)

您也可以替换:

add: function(what) {  // prototype methods here
    this.data.push(what);
}

add: function(what) {  // prototype methods here
    this.data = this.data.concat(what);
}

因为这将创建一个新变量,而不是将其推入原型的实例。

答案 3 :(得分:0)

Object.create可以通过传递带属性描述符的第二个参数来为新对象添加属性。

var sys = require('sys');

var obj = {
    add: function(what){
        this.data.push(what)
    }
};

var one = Object.create(obj, {
    data: {
        value: [],
        writable: true,
        enumerable: true,
        configurable: true
    }
});
one.add(1);

var other = Object.create(obj, {
    data: {
        value: [],
        writable: true,
        enumerable: true,
        configurable: true
    }
});
other.add(2);

sys.puts(other.data.length); // should be 1

当然,您可能希望将其放在构建器函数中,这样您就不会重复:

function makeThing() {
    return Object.create(obj, {
        data: {
            value: [],
            writable: true,
            enumerable: true,
            configurable: true
        }
    });
}

尽管如此,你基本上是在编写一个构造函数(其优点是你不需要用new来调用它)。此外,如果您将writableenumerableconfigurable设置为true,则可以按正常方式设置属性,这可以向后兼容ECMAScript 3实现了Object.create的简单版本:

function makeThing() {
    var newObj = Object.create(obj);
    newObj.data = [];
    return newObj;
}