JS Prototypal继承:childs使用相同的父属性?

时间:2013-04-03 17:23:44

标签: javascript prototypal-inheritance prototype-programming

假设我有Player对象:

var player = function(name) {
    this.handlers = {};
}

player.prototype.on = function(event, callback) {
    if (!this.handlers[event]) {
        this.handlers[event] = [];
    }
    this.handlers[event].push(callback);
}

它很棒,我可以创建玩家,每个玩家都有自己的处理程序。现在假设我需要继承player

var testPlayer = function(name) {
    this.name = name;
};

testPlayer.prototype = new player();

现在,当我创建testPlayer时,每个人共享相同的handlers属性:

var adam = new testPlayer('Adam');
adam.on('test', function(){});

var eve = new testPlayer('Eve');
// eve.handlers == {'test':<function>}

我在这里缺少什么?我理解,每个testPlayer的原型都是我在描述子类时创建的new player对象。但是,有没有办法让所有testPlayers拥有自己的处理程序集?

2 个答案:

答案 0 :(得分:5)

对于那些习惯于经典继承的人来说,这看起来确实很奇怪,但这就是原型继承的工作方式。要为每个实例分配一个处理程序对象,需要在子构造函数上指定一个。这将使原型的属性具有相同的名称:

var testPlayer = function(name) {
    this.name = name;
    this.handlers = {};
};

testPlayer.prototype = new player();

另一种解决方案是使用on方法按需创建此阴影属性:

player.prototype.on = function(event, callback) {
    // Check for a handlers property on the instance
    if(!this.hasOwnProperty('handlers') {
        this.handlers = {};
    }
    if (!this.handlers[event]) {
        this.handlers[event] = [];
    }
    this.handlers[event].push(callback);
}

有趣的事实

如果您要修改原型上对象(或数组)的属性,这只是一个问题。如果您尝试分配原型上存在的属性,则会自动创建本地阴影属性(您无法从实例分配给原型属性)。

答案 1 :(得分:1)

这里的问题是handlers是在构造函数中添加的属性,所以当你这样做时

testPlayer.prototype = new player();

您要将全新player对象的所有属性添加到testPlayer.prototype,而包含 handlers

因此,每个handlers对象中都有一个testPlayer属性,当您向handlers添加属性时,您将属性添加到原型中的对象 < / em>,而不是testPlayer对象。

简而言之,在调用on方法时,您要向testPlayer.prototype.handlers添加属性,而不是adam.handlerseve.handlers

为安全起见,请定义:

var testPlayer = function(name) {
    this.name = name;
    this.handlers = {};
};