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

Kur*_*aze 5 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);
}
Run Code Online (Sandbox Code Playgroud)

它工作得很好,我可以创建玩家,每个人都有自己的处理程序.现在假设我需要继承player:

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

testPlayer.prototype = new player();
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

bfa*_*tto 5

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

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

testPlayer.prototype = new player();
Run Code Online (Sandbox Code Playgroud)

另一种解决方案是从您的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);
}
Run Code Online (Sandbox Code Playgroud)

趣味事实

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