我试图了解如何在nodejs支持的webgame中使属性与原型一起使用。
推理:而不是像Player.attributes.pow.value
那样做
它会更容易阅读:Player.pow
注意:我不想使用函数,因为Player.pow()
让你觉得它不仅仅是返回价值。
因此,为了测试它是如何工作的,我做了一个快速的模型并注意到一个奇怪的行为,虽然它不确定我是否应该这样做:
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 and prototype这是目前的第二个答案。
答案 0 :(得分:2)
为prototype
实例变量分配pow
时,您正在删除附加sayHello
方法的原型的先前定义,因此当您切换声明时,首先进行赋值,然后将实例方法添加到新原型中,以便一切按预期工作。
如果要使用get
方法定义属性而不重新定义整个原型对象,请尝试以下方法:
Object.defineProperty(Player.prototype, "pow", {
get: function() {
return this.attributes.pow.value;
}
});
然后,您可以以相对于sayHello
声明的任何顺序放置该声明,而不必担心意外的副作用。