Javascript recursivo dentro de una clase

Estoy tratando de obtener un método de recursión para trabajar en un contexto de clase. Dentro de mi clase tengo el siguiente método:

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

Sin embargo, cuando uso este método (que funcionó antes, cuando lo usé como function countChildren = ... ) no puedo … encontrar (?): Cannot read property 'countChildren' of undefined en la recursión.

¿Alguien tiene alguna idea?

El problema surge porque dentro de su bucle, this se redefine al scope de la función interna.

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

Intenta enlazar el método en el constructor.
Además, al usar una función de flecha para tu forEach , mantienes el scope de la clase ‘ 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; } } 

El esto dentro del foreach que el este en la clase. En su caso, esto se refiere al elemento actual que se está iterando.

Necesitas atar el scope.

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

la variable this se redefine dentro de:

  1. El scope interno de un bucle for
  2. dentro de una statement de función en línea
  3. Dentro de las llamadas de función asíncronas.

Estoy de acuerdo con Krillgar con la statement de sí mismo. Se solucionó mi problema con una llamada asíncrona.

 obj.prototype.foo = function (string){ var self = this; if(string){ do something } else setTimeout(function(){ self.foo("string"); }, 5000); } 

Intente usar .call() para invocar la función. De esa manera puedes especificar el contexto directamente.

Me gusta esto:

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

Edit: Notado mi error, lo que realmente debería hacer es enlazar la función anónima:

Me gusta esto:

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