Javascript recursion within a class

后端 未结 5 955
轻奢々
轻奢々 2020-12-31 09:28

I am trying to get a recursion method to work in a class context. Within my class I have the following method:

    countChildren(n, levelWidth, level) {
            


        
相关标签:
5条回答
  • 2020-12-31 09:56

    Try binding the method in the constructor.
    Also, by using an arrow function for your 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;
        }
    }
    
    0 讨论(0)
  • 2020-12-31 10:04

    the variable this Gets redefined within:

    1. the inner scope of a for loop
    2. within a inline function declariation
    3. within asynchronous function calls.

    I agree with krillgar with the declaration of self. it fixed my problem with an asynchronous call.

    obj.prototype.foo = function (string){
       var self = this;
       if(string){ do something }
       else
       setTimeout(function(){
         self.foo("string");
         }, 5000);
    }
    
    0 讨论(0)
  • 2020-12-31 10:08

    The this inside the foreach than the this in the class. In your case, this refers to the current element being iterated.

    you need to bind the scope.

    n.children.forEach(function (n) {
       this.countChildren(n, levelWidth, level+1);
    }.bind(this));   
    
    0 讨论(0)
  • 2020-12-31 10:09

    Try using .call() to invoke the function. That way you can specify the context directly.

    Like this:

    this.countChildren.call(this, n, levelWid);th, level+1

    Edit: Noticed my error, what you should really do is bind the anonymous function:

    like this:

      n.children.forEach(function (n) {
        this.countChildren(n, levelWidth, level+1);
      }.bind(this)); 
    
    0 讨论(0)
  • 2020-12-31 10:13

    The problem arises because within your loop, this gets redefined to the inner function scope.

    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;
    }
    
    0 讨论(0)
提交回复
热议问题