2017-07-03 123 views
0

在子类中调用rnd.winner()时,我得到未定义的值。这应该像JOHN一样从父级返回玩家的名字。从子项调用测试函数会从父项返回正确的值win()。调用super.constructor.name作为返回状态返回父母班级名称 - >player现在为什么?在访问父构造函数时,JS类子类返回undefined

class player { 
 
    constructor(name) { 
 
    this.name = name; 
 
    this.win = 0; 
 
    this.loss = 0; 
 
    }; 
 
    win() { 
 
    return this.win; 
 
    }; 
 
    loss() { 
 
    return this.loss; 
 
    }; 
 
}; 
 

 
class scoreBoard extends player { 
 
    constructor(round) { 
 
    super(); 
 
    this.round = round; 
 
    this.emblem = 0; 
 
    }; 
 
    add() { 
 
    return this.round.push([...this.round].pop() + 1); 
 
    } 
 
    winner() { 
 
    return super.name; 
 
    }; 
 
    loser() { 
 
    return super.constructor.name; 
 
    }; 
 
    emblem() { 
 
    return this.emblem; 
 
    }; 
 
    test() { 
 
    return super.win(); 
 
    }; 
 
}; 
 
let plr = new player("JOHN"), 
 
    rnd = new scoreBoard([0]); 
 
console.log(plr.name, rnd.winner(), rnd.test());

+0

不要在普通数据属性中使用'super'。它们始终存在于您当前的实例中。改用'this.name'。 – Bergi

+1

为什么你觉得'scoreBoard'是'player'的扩展?我没有真正理解逻辑。对于记分牌(有赢家和输家的方法),你至少需要两名玩家,所以我不会在继承关系中获得你所希望的。为什么“围绕”一个数组? 'constructor.name'对你的'name'属性有*无关。它是函数的预定义属性(因为'constructor'是一个函数)。 – trincot

回答

0

调用super.constructor.name在孩子返回状态返回父母类名(player)。那为什么呢?

因为这就是super所做的。它不占用自己的constructor属性,而是从您继承的对象上的constructor属性。对于scoreBoard.prototype方法,这是player.prototype对象,而其.constructor.name"player"

根本没有理由使用super,除非您覆盖继承的方法(或构造函数)。这意味着不要使用super以及纯数据属性。它们始终存在于您当前的实例中。改为使用this.…

在子类中调用rnd.winner()时,我得到undefined值。这应该像JOHN一样从父级返回玩家的名字。

这是因为.name未初始化,因为你的孩子上课没有在super()通过对父类的构造参数传递。实际上,你的rnd根本不知道plr实例。

在任何情况下,继承似乎都是描述玩家和记分牌之间关系的错误工具。 Use composition instead - 例如记分牌保存一系列玩家对象来显示。

+0

实际上,如果我做了像super(plr.name);(对我来说看起来完全不正确)和'return this.name',它最终会返回正确的名称。现在很明显,我会努力工作,并找到一个处理'this'的好方法! – NightKn8

+0

是的,这是一种使其工作的方式,而且这是完全不正确的,因为记分牌不是玩家。 – Bergi