How come assigning a property causes "Error: Maximum call stack size exceeded" error?

How come assigning a property causes "Error: Maximum call stack size exceeded" error?

我正在尝试使用 Mozilla 的文档更好地理解 JavaScript getters:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get

我将文章IDE中的代码片段修改为:

const obj = {
  get log() {
    return this.log = 1;
  }
};

console.log(obj.log);

它成功了,产生了这个:

> 1

但是当我尝试将 return 行分开时:

const obj = {
  get log() {
    this.log = 1;
    return this.log;
  }
};

console.log(obj.log);

它出错了:

Error: Maximum call stack size exceeded

我不明白为什么这些看似相同的代码片段会有不同的行为。对 JavaScript 新手有什么建议吗?

感谢您的宝贵时间

更新:
@CertainPerformance 的回答让我明白了一切。

我将添加以下示例代码,以便将来更容易理解。

这就是第二个版本不起作用的原因:

const obj = {
  get log() {
    this.log = 100;
    return this.log; // will go back to line 2 `get log()`
  }
};

console.log(obj.log);

第一个版本有效,因为它正在调用 setter,其中 returns 赋值,因此没有 getter 被递归调用。

如果有理由需要第二个版本,那么使用不同的 属性 名称将避免递归调用。

const obj = {
  get log() {
    this._log = 100;
    return this._log;
  }
};

console.log(obj.log);
console.log(obj._log);

log是一个getter,但你没有关联setter,正在做

return this.log = 1;

尝试以 setter 的形式访问 log(因为它是 setter/getter 属性)- 但 setter 不存在,因此它要么

  • 草率模式下静默失败
  • 在严格模式下抛出错误

'use strict';
const obj = {
  get log() {
    return this.log = 1;
  }
};

console.log(obj.log);

相比之下,做

return this.log;

也在 log 上调用 getter。但是您已经在 log 的 getter 中,导致无限循环。

您可能想为内部 属性 和外部 属性 使用不同的 属性 名称 - 如 _log,或使用私有字段,或类似的名称那。