Javascript recursion in class
I am trying to get a recursion method to work in the context of a class. In my class, I have the following method:
countChildren(n, levelWidth, level) {
if (n.children && n.children.length > 0) {
if (levelWidth.length <= level + 1) {
levelWidth.push(0);
}
levelWidth[level + 1] += n.children.length;
n.children.forEach(function (n) {
this.countChildren(n, levelWidth, level+1);
});
}
// Return largest openend width
return levelWidth;
}
However, when I use this method (which worked before I used it like function countChildren = ...
), it cannot ... find (?) Itself: Cannot read property 'countChildren' of undefined
in recursion.
Does anyone have any ideas?
source to share
The problem comes from being this
overridden in your loop to the scope of the inner function.
countChildren(n, levelWidth, level) {
var self = this; // Get a reference to your object.
if (n.children && n.children.length > 0) {
if (levelWidth.length <= level + 1) {
levelWidth.push(0);
}
levelWidth[level + 1] += n.children.length;
n.children.forEach(function (n) {
// Use "self" instead of "this" to avoid the change in scope.
self.countChildren(n, levelWidth, level+1);
});
}
// Return largest openend width
return levelWidth;
}
source to share
Try to bind the method in the constructor.
Also, by using the arrow function for yours forEach
, you keep the scope of the class this
.
export class MyClass {
constructor(){
this.countChildren = this.countChildren.bind(this);
}
countChildren(n, levelWidth, level){ ... }
countChildren(n, levelWidth, level) {
if (n.children && n.children.length > 0) {
if (levelWidth.length <= level + 1) {
levelWidth.push(0);
}
levelWidth[level + 1] += n.children.length;
n.children.forEach( n => { // arrow function do not need to rebind this
this.countChildren(n, levelWidth, level+1);
});
}
// Return largest openend width
return levelWidth;
}
}
source to share
Try using .call()
to call a function. This way you can specify the context directly.
Like this:
this.countChildren.call(this, n, levelWid);
th, level + 1
Edit: Seeing my mistake, you should actually bind the anonymous function:
like this:
n.children.forEach(function (n) {
this.countChildren(n, levelWidth, level+1);
}.bind(this));
source to share