Resumidamente sobre isso nas funções javascript

Prefácio



Há muitas informações na Internet sobre como isso funciona, mas o tempo todo eu não tinha literalmente um pouco o suficiente para entendê-lo completamente.



Recentemente, no entanto, como me parece, fiz isso e gostaria de compartilhar com vocês.



Sem muitas palavras



Cobriremos exemplos simples e complexos - para que todos se interessem.



Há dois pontos principais que examinaremos:



(1) Para funções declaradas por meio de function () {}, isso é calculado no momento da chamada.

(2) Para funções de seta, isso é definido quando a função é criada.



Vamos começar com alguns exemplos simples.



function globalFunc() {
  console.log(this);
}
const globalArrowFunc = () => {
  //      ,  this - window/undefined
  //   ,   use strict   this === undefined
  console.log(this);
}

globalFunc(); // undefined
globalArrowFunc(); // undefined


E se adicionarmos essas funções ao objeto:



const cat = {
  name: 'Pirate',
  globalFunc,
  globalArrowFunc
};

cat.globalFunc(); // { name: 'Pirate', ... }
cat.globalArrowFunc(); // undefined


Vamos descobrir.



Chamar cat.globalFunc () nos retornou um objeto gato. Para facilitar o entendimento, você pode pensar assim "isso, ao chamar funções declaradas por meio da função () {}, será igual ao objeto antes do ponto".



Então, por que cat.globalArrowFunc () retornou undefined para nós? O fato é que o valor this para uma função seta é determinado no momento de sua criação, e quando a criamos, o valor this era indefinido.



Agora, vamos criar um objeto com alguns métodos:



const dog = {
  name: 'Viking',
  //        
  //       
  localFunc: function() {
    console.log(this);
  },
  localArrowFunc: () => {
    console.log(this);
  }
};

dog.localFunc(); // { name: 'Viking', ... }
dog.localArrowFunc(); // undefind


Por que é que?



dog.localFunc () - porque o objeto antes do ponto dog.

dog.localArrowFunc () - porque dentro do objeto também é um objeto global, o que significa que ficamos indefinidos.



Vamos complicar um pouco nosso exemplo.



const dog = {
  name: 'Viking',
  localFunc: function() {
    const arrowFuncInLocalFunc = () => {
      console.log(this);
    };
    function funcInLocalFunc() {
      console.log(this);
    };
    arrowFuncInLocalFunc(); // 1
    funcInLocalFunc(); // 2
  },
  localArrowFunc: () => {
    const arrowFuncInLocalArrowFunc = () => {
      console.log(this);
    };
    function funcInLocalArrowFunc() {
      console.log(this);
    };
    arrowFuncInLocalArrowFunc(); // 3
    funcInLocalArrowFunc(); // 4
  }
};

dog.localFunc();
// 1 - { name: 'Viking', ... }
// 2 - undefind
dog.localArrowFunc();
// 3 - undefind
// 4 - undefind


Vamos descobrir!



(1) arrowFuncInLocalFunc () // {name: 'Viking',…}



Por que isso está acontecendo?



Porque quando criamos o objeto, escrevemos a função localFunc. E, como lembramos dos exemplos anteriores, para ela este é o objeto antes do ponto, ou seja, {nome: 'Viking', ...}. Agora vamos falar sobre a função arrowFuncInLocalFunc em si - ela é criada imediatamente quando localFunc é chamado e lembra o valor this que estava no local de sua criação. Então, obtemos que arrowFuncInLocalFunc nos retorna {nome: 'Viking',…}.



(2) funcInLocalFunc () // undefind



Por que isso está acontecendo?



Como dissemos anteriormente, para funções declaradas via function () {} esse valor é determinado no momento da chamada e é igual ao objeto antes do ponto. Nesse caso, não temos um objeto na frente do ponto, o que significa que este é um objeto global ou, no nosso caso, indefinido.



(3) arrowFuncInLocalArrowFunc () // undefined



Por que isso está acontecendo?



Este exemplo é muito semelhante a (1), apenas nossa função arrowFuncInLocalArrowFunc é criada dentro da mesma função de seta. Também lembramos que as funções de seta no momento de sua declaração gravam nesse valor a partir de seu ambiente. No entanto, nossa função foi criada dentro de localArrowFunc, para a qual ele é indefinido. Isso significa que para arrowFuncInLocalArrowFunc isso será indefinido.



(4) funcInLocalArrowFunc () // undefined



Por que isso está acontecendo?



Exatamente o mesmo motivo de (2) para funcInLocalFunc.



Vejamos outro exemplo:



const cat = {
  name: 'Tom',
  getFuncWithTomName: function() {
    return () => {
      console.log(this.name);
    }
  }
};

const mouse = {
  name: 'Jerry',
  logName: cat.getFuncWithTomName()
};

mouse.logName(); // Tom o_O !?


Isso ocorre porque getFuncWithTomName cria e retorna uma função de seta e, quando a função de seta é criada, é igual a getFuncWithTomName. E para getFuncWithTomName, este é o objeto antes do ponto (cat).



Total



O contexto das funções de seta é determinado quando são criadas.



O contexto para function () {} é determinado quando eles são chamados e é igual ao objeto antes do ponto.



All Articles