Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

238
Visualizações
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 Respostas
Responde à pergunta

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda