I have the following code.
class Node {
constructor(value, parent, possibleChildren = []) {
this.value = value;
this.parent = parent;
this.children = []
this.setChildren(possibleChildren);
}
setChildren(possibleChildren) {
if (possibleChildren.length === 0) return [];
while (possibleChildren.length > 0) {
const value = possibleChildren.pop();
// keyword *this* messes up the context. Save them function calls for lazy execution
let childNode = () => new Node(value, this, possibleChildren);
this.children.push(childNode);
}
this.children = this.children.map(child => child())
}
getChildrenValues() {
return this.children.map((child) => child.value);
}
}
In the above the this.children
variable is set properly. If I save the this.children
array directly, without wrapping it in a function, I see incorrect children being set.
Example:
setChildren(possibleChildren) {
if (possibleChildren.length === 0) return [];
while (possibleChildren.length > 0) {
const value = possibleChildren.pop();
// keyword *this* messes up the context. Save them function calls for lazy execution
let childNode = new Node(value, this, possibleChildren);
this.children.push(childNode);
}
}
I know that the context of this is not consitent without the function wrapper. What I do not understand is why. Any ideas?
Calling getChildrenValues
on the first example returns ["A", "B", "C"].
Calling getChildrenValues
on the second example returns ["C"]
class Node {
constructor(value, parent, possibleChildren = []) {
this.value = value;
this.parent = parent;
this.children = []
this.setChildren(possibleChildren);
}
setChildren(possibleChildren) {
if (possibleChildren.length === 0) return [];
while (possibleChildren.length > 0) {
const value = possibleChildren.pop();
// keyword *this* messes up the context. Save them function calls for lazy execution
const childNode = new Node(value, this, possibleChildren);
this.children.push(childNode);
}
}
getChildrenValues() {
return this.children.map((child) => child.value);
}
}
let root = new Node(null, null, "ABC".split(""));
console.log(root.getChildrenValues())