I'm reading up on JavaScript's virtual getter using Mozilla's documentation: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get
In it there's a section with some example code:
In the following example, the object has a getter as its own property. On getting the property, the property is removed from the object and re-added, but implicitly as a data property this time. Finally, the value gets returned.
get notifier() { delete this.notifier; return this.notifier = document.getElementById('bookmarked-notification-anchor'); },
This example comes right after the article talks about lazy/smart/memoized, but I am not seeing how the code is an example of a lazy/smart/memoized getter.
Or is that section talking about something else completely?
It just feels like I'm not following the flow of the article and it might be because I do not understand some key concept.
Please let me know if I'm just over-thinking this and that section was just shoehorned in or if the section really does relate to lazy/smart/memoized somehow.
Thank you for your guidance
Update 1:
I guess maybe I don't know how to verify that the code is getting memoized.
I tried to run this in the IDE on the page:
const obj = {
log: ['a', 'b', 'c'],
get latest() {
if (this.log.length === 0) {
return undefined;
}
return this.log[this.log.length - 1];
},
get notifier() {
delete this.notifier;
return this.notifier = document.getElementById('bookmarked-notification-anchor');
},
};
console.log(obj.latest);
// expected output: "c"
console.log(obj.notifier); // returns null
This seems more appropriate, but I can't verify that the cache is being used:
const obj = {
log: ['a', 'b', 'c'],
get latest() {
if (this.log.length === 0) {
return undefined;
}
return this.log[this.log.length - 1];
},
get notifier() {
delete this.notifier;
return this.notifier = this.log;
},
};
console.log(obj.latest);
// expected output: "c"
console.log(obj.notifier); // Array ["a", "b", "c"]
console.log(obj.notifier); // Array ["a", "b", "c"]
I guess I'm not sure why does the property need to be deleted first, delete this.notifier;? Wouldn't that invalidate the cache each time?
Update 2: @Bergi, thanks for the suggested modifications to the example code.
I ran this (with the delete):
const obj = {
log: ['a', 'b', 'c'],
get latest() {
if (this.log.length === 0) {
return undefined;
}
return this.log[this.log.length - 1];
},
get notifier() {
delete this.notifier;
return this.notifier = console.log("heavy computation");
},
};
console.log(obj.latest);
// expected output: "c"
obj.notifier;
obj.notifier;
and got:
> "c"
> "heavy computation"
I ran this (without the delete):
const obj = {
log: ['a', 'b', 'c'],
get latest() {
if (this.log.length === 0) {
return undefined;
}
return this.log[this.log.length - 1];
},
get notifier() {
//delete this.notifier;
return this.notifier = console.log("heavy computation");
},
};
console.log(obj.latest);
// expected output: "c"
obj.notifier;
obj.notifier;
and got:
> "c"
> "heavy computation"
> "heavy computation"
So that definitely, proves memoization is happening. Maybe there's too much copying and pasting updates to the post, but I'm having a hard time understanding why the delete is necessary to memoize. My scattered and naive brain is thinking that the code should memoize when there is no delete.
Sorry, I'll need to sit and think about it some. Unless you have a quick tip on how to understand what's going on.
Thank you again for all of your help
Update 3:
I guess I'm still missing something.
From Ruby, I understand memoization as:
if it exists/pre-calculated, then use it; if it does not exist, then calculate it
something along the lines of:
this.property = this.property || this.calc()
With the delete in the example code snippet, wouldn't the property always not exist and, hence, would always need to be recalculated?
There's definitely something wrong with my logic, but I am not seeing it. I guess maybe it's a "I don't know what I don't know" scenario.