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?

+3
javascript class recursion


source to share


4 answers


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;
}

      

+5


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;
    }
}

      

+4


source to share


It is inside foreach than it is in class. In your case, this means the current element is being repeated.

you need to bind the scope.

n.children.forEach(function (n) {
   this.countChildren(n, levelWidth, level+1);
}.bind(this));   

      

0


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)); 

      

-1


source to share







All Articles
Loading...
X
Show
Funny
Dev
Pics