【发布时间】:2021-09-10 10:27:37
【问题描述】:
我正在尝试使用 Mozilla 的文档更好地理解 JavaScript getters:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get
我将文章IDE中的代码sn-p修改成这样:
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
我不明白为什么这些看似等效的 sn-ps 代码的行为会有所不同。对 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,因此不会递归调用 getter。
如果有理由需要第二个版本,那么使用不同的属性名称将避免递归调用。
const obj = {
get log() {
this._log = 100;
return this._log;
}
};
console.log(obj.log);
console.log(obj._log);
【问题讨论】:
-
对属于 getter 的属性使用 getter 或 setter 几乎总是一个坏主意,因为这会创建循环引用。如果你得到
x,那么你必须得到x,这会导致另一个得到x....等等。 -
至于您的 sn-ps - 第一个恰好没有读取
log的值,这意味着它不会再次触发get log()。但这仍然是不好的做法。 -
另外,在您的第一个代码中,它返回 1,因为您正在执行类似
abc = 1;的操作,这将始终返回 1,您也可以将this.log更改为this.xyz。 -
在 chrome 控制台中执行 abc = 1。
标签: javascript get getter-setter getter