Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

228
Vistas
Understanding the context of *this* inside classes

I have the following code.

class Node {
     constructor(value, parent, possibleChildren = []) {
     this.value = value;
     this.parent = parent;
     this.children = []
     this.setChildren(possibleChildren);
   }

setChildren(possibleChildren) {
  if (possibleChildren.length === 0) return [];

  while (possibleChildren.length > 0) {
      const value = possibleChildren.pop();
      // keyword *this* messes up the context. Save them function calls for lazy execution
      let childNode = () => new Node(value, this, possibleChildren);
      this.children.push(childNode);
    }
    this.children = this.children.map(child => child())
  }

getChildrenValues() {
    return this.children.map((child) => child.value);
  }
}

In the above the this.children variable is set properly. If I save the this.children array directly, without wrapping it in a function, I see incorrect children being set.

Example:

setChildren(possibleChildren) {
  if (possibleChildren.length === 0) return [];

  while (possibleChildren.length > 0) {
    const value = possibleChildren.pop();
    // keyword *this* messes up the context. Save them function calls for lazy execution
    let childNode = new Node(value, this, possibleChildren);
    this.children.push(childNode);
  }
}

I know that the context of this is not consitent without the function wrapper. What I do not understand is why. Any ideas?

Calling getChildrenValues on the first example returns ["A", "B", "C"].

Calling getChildrenValues on the second example returns ["C"]

class Node {
  constructor(value, parent, possibleChildren = []) {
    this.value = value;
    this.parent = parent;
    this.children = []
    this.setChildren(possibleChildren);
  }

  setChildren(possibleChildren) {
    if (possibleChildren.length === 0) return [];

    while (possibleChildren.length > 0) {
      const value = possibleChildren.pop();
      // keyword *this* messes up the context. Save them function calls for lazy execution
      const childNode = new Node(value, this, possibleChildren);
      this.children.push(childNode);
    }
  }
  
  getChildrenValues() {
    return this.children.map((child) => child.value);
  }
}

let root = new Node(null, null, "ABC".split(""));
console.log(root.getChildrenValues())

about 4 years ago · Santiago Trujillo
1 Respuestas
Responde la pregunta

0

I know that the context of this is not consistent without the function wrapper. What I do not understand is why?

This has nothing to do with the this keyword. Since you used an arrow function, it does refer to exactly the same object in both your code snippets, there is no difference.

The reason why you get different results from the two snippets is the lazy execution, but not with respect to this, but rather the possibleChildren array. In your first code, the while (possibleChildren.length > 0) runs and empties the possibleChildren array before you do the recursive new Node calls. In the second example, you call new Node during that loop, and you pass on the reference to the same possibleChildren array, which is being emptied by the recursive call and the loop therefore terminates right after the first iteration.

To fix this, just don't recursively pass the possibleChildren:

class Node {
  constructor(value, parent, childrenValues = []) {
    this.value = value;
    this.parent = parent;
    this.children = []
    this.setChildrenValues(childrenValues);
  }

  setChildrenValues(childrenValues) {
    for (let i=childrenValues.length; i--; ) {
      const value = childrenValues[i];
      const childNode = new Node(value, this  );
//                                           ^ no third argument, no grandchildren
      this.children.push(childNode);
    }
  }
  
  getChildrenValues() {
    return this.children.map((child) => child.value);
  }
}

let root = new Node(null, null, "ABC".split(""));
console.log(root.getChildrenValues())

about 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda