【问题标题】:The set and get methods of a property on the prototype aren't shadowed from the corresponding property on the instance which has no set-get methods原型上属性的 set 和 get 方法不会从没有 set-get 方法的实例上的相应属性中隐藏
【发布时间】:2020-03-21 23:03:17
【问题描述】:

我有来自Eric Faust ES6 class syntax sugar的以下代码:

function Circle(radius) {
      this.radius = radius;
      Circle.circlesMade++;
  }

  Circle.draw = function draw(circle, canvas) { /* Canvas drawing code */ }

  Object.defineProperty(Circle, "circlesMade", {
      get: function() {
          return !this._count ? 0 : this._count;
      },

      set: function(val) {
          this._count = val;
      }
  });

  Circle.prototype = {
      area: function area() {
          return Math.pow(this.radius, 2) * Math.PI;
      }
  };

  Object.defineProperty(Circle.prototype, "radius", {
      get: function() {
          return this._radius;
      },

      set: function(radius) {
          if (!Number.isInteger(radius))
              throw new Error("Circle radius must be an integer.");
          this._radius = radius;
      }
  });

  let x = new Circle("pippo");

而且我不明白为什么会启动异常。 setter 和 getter 方法与 radius 访问器属性上的原型 Circle.prototype 相关联,而不是当我创建 x 实例时,我也设置了 radius 属性,但在构造函数中,因此我希望 setter 和 getter 不是触发(再次因为实例上的radius 属性和原型上的radius 属性是在两个不同的对象上定义的)。在这种情况下,我想念 setter 和 getter 的工作方式。有人可以澄清一下吗?

还有一个无关紧要的小问题,是在构造函数Circle上定义static属性circlesMade还是在原型上定义更正确?

【问题讨论】:

    标签: javascript


    【解决方案1】:

    在构造函数中,对this.radius 的赋值是对this 的“半径”属性的赋值。 this 的值当然是新创建的对象,并且在构造函数代码运行时,该对象的原型链已经建立。因此“半径”的设置器肯定会被调用,你会得到异常。

    setter 和 getter 方法确实在原型上,但这样做的重点是让每个实例都共享该行为。构造函数中this 引用的对象就是这些实例之一。

    对于没有 getter/setter 函数的“简单”原型属性,在构造函数或其他任何地方分配给 this.whatever 将始终在目标对象上创建一个属性本地,而不是更改原型上的属性值。带有 getter/setter 方法的属性不能这样工作。

    请注意,构造函数中的代码与任何其他函数中的代码都遵循不同的规则。在进入函数和退出函数的过程中会发生特殊的事情,否则就是普通的代码。

    【讨论】:

    • circlesMade 属性正确放置在构造函数对象上。
    • Set 和 get 方法关联到一个属性,即原型上的半径,并且由于原型上的半径被实例上的半径属性遮蔽(这个)我认为 set-get 方法不是触发(因为它们没有关联到实例上的 radius 属性)。但显然情况并非如此。
    • 是的,事实并非如此。当原型上的属性是 getter/setter 属性时,它基本上是原型上一种特殊的 method 属性。因此方法调用的规则适用。
    • 在 ES2015 规范的第 9.1.9 节中以通常钝的语言进行了详细说明。如果属性被解析为 getter/setter 属性,则会跳过创建新 instance 属性的正常行为,并调用 setter。
    • 谢谢。这条评论是我怀疑的答案。如果需要,请填写您的主要答案,以便我接受这个答案来解决我的问题(以及未来的观众)。
    猜你喜欢
    • 2015-08-19
    • 2013-05-20
    • 1970-01-01
    • 2013-12-26
    • 2013-10-24
    • 2017-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多