简体   繁体   English

JS。 原型怪异行为中的属性

[英]JS. properties in prototype weird behaviour

I'm trying to understand how to make properties work with prototype in a nodejs backed webgame. 我试图了解如何在Node.js支持的网络游戏中使属性与原型一起使用。

Reasoning: Instead of doing something like: Player.attributes.pow.value It would be so much easier to read when it's: Player.pow Note: I do not want to use a function because Player.pow() makes you feel like it's doing more than just return a value. 推理:而不是执行以下操作: Player.attributes.pow.value当它Player.pow时,它将更容易阅读: Player.pow注意:我不想使用函数,因为Player.pow()使您感觉像是不仅仅是返回值。

So to test how it works I did a quick mockup and noticed an odd behaviour and although it works not sure if I should be doing this: 因此,为了测试它的工作方式,我做了一个快速的模型并注意到了一个奇怪的行为,尽管它不能确定我是否应该这样做:

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();

It says TypeError: p.sayHello is not a function 它说TypeError: p.sayHello is not a function

But if I put it below defining the property, it works 但是,如果我将其放在定义属性的下面,它就可以工作

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

What's going on here? 这里发生了什么? Is this a bad way of doing it? 这是一个坏方法吗? I saw an example of this here: JS defineProperty and prototype It is the second answer at the moment. 我在这里看到了一个示例: JS defineProperty和prototype这是当前的第二个答案。

When you assign the prototype for the pow instance variable, you are erasing the previous definition for the prototype to which the sayHello method is attached, so when you switch the declarations, the assignment happens first and then you add the instance method to the new prototype so everything works as expected. 当为pow实例变量分配prototype ,您将擦除为附加了sayHello方法的原型的先前定义,因此,在切换声明时,首先进行分配,然后将实例方法添加到新原型中所以一切都按预期进行。

If you want to define a property with a get method without redefining the entire prototype object, try something like this: 如果要使用get方法定义属性而不重新定义整个原型对象,请尝试如下操作:

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

You may then place that declaration in any order relative to the sayHello declaration without worrying about unexpected side-effects. 然后,您可以相对于sayHello声明以任何顺序放置该声明,而不必担心意外的副作用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM