为什么 JavaScript getter 方法在执行之前、期间和之后进行更改?

Why JavaScript getter method make changes before, during and after its execution?

我使用 ES6 class 构建对象,如下创建任何汽车的制造商和速度 属性,我还放置了一个 getter 将速度转换为英里。

class CarCL {
  constructor(make, speed) {
    this.make = make;
    this.speed = speed;
  }

  // Converts current speed in mi/h
  get speedUS() {
    return (this.speed /= 1.6);
  }
}

const carFord = new CarCL('Ford', 120);
console.log(carFord);
console.log(carFord.speedUS);

我在控制台中得到了奇怪的结果,如下图所示。

为什么在 getter 方法之前将速度转换为 75,并且它继续继续转换为 46.875,并且它再次在 CarCL.prototype 对象中自行更改为原型 29.296875福特汽车?

在您的 speedUS() getter 中,您使用 /= 将结果赋值回左操作数。如果您不想要那个(您可能不想要),则将 /= 更改为 /.

改变这个:

 return (this.speed /= 1.6);

对此:

 return (this.speed / 1.6);

另请注意,getter 突变 属性 的整个概念通常是错误的(我假设您不是故意让它发生突变)。 getter 不应发生变异。这是一个getter。使用setter进行变异。

class CarCL {
  constructor(make, speed) {
    this.make = make;
    this.speed = speed;
  }

  // Converts current speed in mi/h
  get speedUS() {
    return (this.speed / 1.6);
  }
}

const carFord = new CarCL('Ford', 120);
console.log(carFord);
console.log(carFord.speedUS);


为了补充一点解释,您还发现 console.log() 在某些浏览器中的工作方式很奇怪。您会认为您的代码应该首先显示未修改的 carFord 对象,然后 carFord.speedUS getter 才会修改该对象。事实上,如果你 运行 你的代码在 nodejs 中,这就是你所看到的。

但是,在某些浏览器中,传递给 console.log() 的对象的评估和显示是“惰性的”,这意味着它不会立即发生,因此 carFord.speedUS getter 运行s 在控制台输出 carFord 之前,即使这不是语句的顺序。这是 console.log() 实现中的一个怪异现象(在 Chrome 中经常看到),可能是由于一些性能优化,以尽量不减慢执行速度。

如果您将代码更改为:

const carFord = new CarCL('Ford', 120);
console.log(JSON.stringify(carFord));
console.log(carFord.speedUS);

然后您可以看到您期望的内容:

{ "make": "Ford", "speed": 120 }
75

当然,如果您修复 speedUS() getter 不改变对象,那么所有这些都没有实际意义。

问题出在这一行:

    return (this.speed /= 1.6);

/=division assignment,所以您实际上是在说“将 this.speed 设置为其当前值除以 1.6”。

正如您所注意到的,变异 getter 非常令人困惑。相反,说 return (this.speed / 1.6); 它会按照您的预期运行。