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 getter
s: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
,或使用私有字段,或类似的名称那。
我正在尝试使用 Mozilla 的文档更好地理解 JavaScript getter
s: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
,或使用私有字段,或类似的名称那。