为什么 JavaScript getter 方法在执行之前、期间和之后都会发生变化?

发布于 2025-01-10 01:08:45 字数 639 浏览 4 评论 0原文

我使用 ES6 类构造了对象,如下创建任何汽车的品牌和速度属性,并且还放置了一个 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 福特汽车的原型是什么?

I constructed object using ES6 class, creating make and speed property of any car as follows, and also I put a getter to convert speed into miles.

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

I got weird result in console as following image.

enter image description here

Why speed is converted to 75 before getter method and further it keeps continued to be converted to 46.875 and also again it made changes to on it own in CarCL.prototype object to 29.296875 which is prototype of carFord?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

辞旧 2025-01-17 01:08:45

问题是这一行:

    return (this.speed /= 1.6);

/= is 除法分配,因此您实际上是在说“将 this.speed 设置为其当前值除以 1.6”。

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

The problem is this line:

    return (this.speed /= 1.6);

/= is division assignment, so you're effectively saying "set this.speed to its current value divided by 1.6".

A mutating getter is extremely confusing, as you've noticed. Instead, say return (this.speed / 1.6); and it'll behave as you'd expect.

梦幻的心爱 2025-01-17 01:08:45

speedUS() getter 中,您使用 /= 将结果分配回左侧操作数。如果您不希望这样(您可能不希望如此),请将 /= 更改为 /

将其更改

 return (this.speed /= 1.6);

为:

 return (this.speed / 1.6);

还要注意,改变它所获得的属性的 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 在控制台输出 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 以不改变对象,那么所有这些都是没有意义的。

In your speedUS() getter, you are using /= which assigns the result back to the left operand. If you don't want that (which you presumably do not), then change /= to just /.

Change this:

 return (this.speed /= 1.6);

to this:

 return (this.speed / 1.6);

Note also that the whole concept of a getter that mutates the property it is getting is generally bad (I assume you didn't mean for it to mutate). A getter should not mutate. It's a getter. Use a setter to mutate.

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


To add one further point of explanation, you are also seeing a weirdness in how console.log() works in some browsers. You would think that your code should first show the unmodified carFord object and, then and only then, would the carFord.speedUS getter modify the object. In fact, if you run your code in nodejs, that's what you see.

But, in some browsers, the evaluation and display of an object passed to console.log() is "lazy" meaning it doesn't happen immediately and thus the carFord.speedUS getter runs before the console outputs carFord even though that isn't the order of the statements. This is a weirdness in the console.log() implementation (seen regularly in Chrome) and is probably due to some performance optimizations to try to not slow down execution any more than necessary.

If you changed your code to this:

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

You could then see what you expect:

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

Of course, all this is moot if you fix the speedUS() getter to not mutate the object.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文