I'm trying to better understand JavaScript getter
s using Mozilla's documentation: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get
I modified the code snippet in the article's IDE to this:
const obj = {
get log() {
return this.log = 1;
}
};
console.log(obj.log);
and it worked, yielding this:
> 1
But when I try to separate out the return
line to this:
const obj = {
get log() {
this.log = 1;
return this.log;
}
};
console.log(obj.log);
it errors out with:
Error: Maximum call stack size exceeded
I can't figure out why these seemingly equivalent snippets of code would behave differently. Any advice for a JavaScript newbie?
Thank you for your time 🙏🏻
Update:
@CertainPerformance's answer cleared everything up for me.
I'm going to add the following example code to make it easier for me to understand in the future.
This is why the second version did not work:
const obj = {
get log() {
this.log = 100;
return this.log; // will go back to line 2 `get log()`
}
};
console.log(obj.log);
The first version works because it is calling the setter which returns the value assigned so no getter
was recursively called.
If there is a reason to need the second version, then using a different property name will avoid the recursive calling.
const obj = {
get log() {
this._log = 100;
return this._log;
}
};
console.log(obj.log);
console.log(obj._log);
When log
is a getter, but you have no associated setter, doing
return this.log = 1;
tries to access log
as a setter (since it's a setter/getter property) - but no setter exists, so it'll either
'use strict';
const obj = {
get log() {
return this.log = 1;
}
};
console.log(obj.log);
In contrast, doing
return this.log;
invokes the getter on log
too. But you're already in log
's getter, resulting in an infinite loop.
You probably want to use a different property name for the internal property and the external property - like _log
, or with private fields, or something like that.