JS。 属性原型奇怪的行为

我试图了解如何使一个nodejs支持的webgame中的原型的属性工作。

推理:而不是像这样做: Player.attributes.pow.value它会更容易阅读时,它是: Player.pow注意:我不想使用一个函数,因为Player.pow()让你感觉像是不仅仅是返回一个值。

所以要testing它是如何工作的,我做了一个快速的模型,并注意到一个奇怪的行为,虽然它不知道我是否应该这样做:

 function Player() { this.attributes = { pow: { base: 3, value: 3, attChanges: [], multiplier: 0, calculateValue: function() { var multiplier = this.multiplier; var value = 0; this.attChanges.forEach( function(att) { value += att.value; // For some reason this.value returns NaN in the forEach, this is a way around that... multiplier += att.multiplier; }); this.value = this.base + value; this.value *= (1 + multiplier / 100); } } } //Change a attribute and calculate it's value this.attributes.pow.attChanges.push({value: 3, multiplier: 0}); this.attributes.pow.calculateValue(); } Player.prototype.sayHello = function() { console.log("hello"); } Player.prototype = { get pow() { return this.attributes.pow.value; } } var p = new Player(); p.sayHello(); // Error console.log(p.pow); console.log(p.pow); p.sayHello(); 

它说TypeError: p.sayHello is not a function

但是如果我把它定义在财产的定义之下,它是有效的

 Player.prototype = { get pow() { return this.attributes.pow.value; } } Player.prototype.sayHello = function() { console.log("hello"); } var p = new Player(); p.sayHello(); // hello console.log(p.pow); // 6 console.log(p.pow); // 6 p.sayHello(); // hello 

这里发生了什么? 这是做这个不好的方法吗? 我在这里看到了一个例子: JS defineProperty和prototype这是目前的第二个答案。

当您为pow实例variables指定prototype ,您将删除以前定义的sayHello方法所连接的原型,因此当您切换声明时,将首先进行赋值,然后将实例方法添加到新原型所以一切按预期工作。

如果你想用一个get方法来定义一个属性而不重新定义整个原型对象,可以尝试如下所示:

 Object.defineProperty(Player.prototype, "pow", { get: function() { return this.attributes.pow.value; } }); 

然后,您可以按照与sayHello声明相关的任何顺序放置该声明,而不必担心意外的副作用。