2017-07-17 37 views
2

我想獲得遞歸方法在類上下文中工作。在我的課,我有以下方法:一個類內的Javascript遞歸

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

然而,當我用這個方法(這時候我只是用它作爲function countChildren = ...工作過),它不能...發現自己(?):Cannot read property 'countChildren' of undefined在遞歸。

有沒有人有任何想法?

+0

這是因爲'forEach'的回調函數有它自己的作用域,並且將'this'的值設置爲類以外的類。 – adeneo

回答

5

問題出現是因爲在您的循環中,this被重新定義爲內部函數範圍。

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

好抓@krillgar。 – colecmc

+0

這個工作非常好!謝謝你的幫助 –

+2

我不是'那個=這個'技巧的粉絲。有一些構造是這個特定用例的語言的一部分,主要是ES6中的'.bind()'和箭頭函數。 –

4

嘗試綁定構造函數中的方法。
此外,通過對您的forEach使用箭頭函數,您可以保留類「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

這可能有效,但我發現@ krillgar的答案是最直接的。謝謝你的回覆。 –

+0

看到我對'that = this'技巧的評論。由於您使用了類,因此您使用的是ES6語法,這意味着您可以訪問箭頭函數,而不會重新指定「this」的範圍。試試吧。你的代碼會感謝你。 –

+0

嗯...好吧我會再看看 –

-1

嘗試使用.call()來調用該函數。這樣你可以直接指定上下文。

像這樣:

this.countChildren.call(this, n, levelWid);日級別+ 1

編輯: 注意到了我的錯誤,你真的應該做的是綁定匿名函數:

這樣的:

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

這個裏面的foreach比這個在課上。在你的情況下,這是指正在迭代的當前元素。

您需要綁定範圍。

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