[ad_1]

JavaScript’s this palavra-chave é um dos aspectos mais difíceis de entender da linguagem. Mas é extremamente importante para escrever código JavaScript mais avançado.

Em JavaScript, o this palavra-chave nos permite:

  • Reutilizar funções em diferentes contextos e
  • Identifique em qual objeto focar quando um método é invocado.

Quando se trata de this, a pergunta importante a fazer é onde a função é invocada. Porque não sabemos o que está no this palavra-chave até que a função seja chamada.

O uso de this pode ser categorizado em cinco diferentes binding aspectos. Neste artigo, aprenderemos sobre todos os cinco aspectos com exemplos.

Em JavaScript, um Lexical Environment é onde seu código é fisicamente escrito. No exemplo abaixo, o nome da variável é lexically dentro da função sayName().

function sayName() {  let name="someName";  console.log('The name is, ', name); }

A Execution Context refere-se ao código que está sendo executado atualmente e tudo o mais que ajuda a executá-lo. Pode haver muitos ambientes lexicais disponíveis, mas um atualmente a execução é gerenciada pelo Contexto de Execução.

Ambiente léxico vs contexto de execução

Cada um dos contextos de execução contém um Environment Record. Binding em JavaScript significa registrar o identificador (variável e nome da função) em um registro de ambiente específico.

Nota: Binding ajuda a associar o identificador (variável e nome da função) com o this palavra-chave para um execution context.

Não se preocupe se achar isso um pouco difícil de entender agora. Você terá uma melhor compreensão à medida que prosseguirmos.

A ligação implícita cobre a maioria dos casos de uso para lidar com o this palavra-chave.

Na vinculação implícita, você precisa verificar o que é à esquerda do operador ponto (.) adjacente a uma função no momento da invocação. Isso determina o que this está vinculado a.

Vejamos um exemplo para entender melhor.

let user = {    name: 'Tapas',    address: 'freecodecamp',    getName: function() {        console.log(this.name);    }};user.getName();

Aqui this está vinculado ao objeto de usuário. Sabemos disso porque, à esquerda do operador ponto (.) Adjacente à função getName(), nós vemos o user objeto. então this.name vai logar Tapas no console.

Vamos ver outro exemplo para entender melhor esse conceito:

function decorateLogName(obj) {      obj.logName = function() {          console.log(this.name);      }  };  let tom = {      name: 'Tom',      age: 7  };  let jerry = {      name: 'jerry',      age: 3  };  decorateLogName(tom);  decorateLogName(jerry);  tom.logName();  jerry.logName();

Neste exemplo, temos dois objetos, tom e jerry. Decoramos (aprimoramos) esses objetos anexando um método chamado logName().

Observe que quando invocamos tom.logName(), a tom o objeto está à esquerda do operador ponto (.) adjacente à função logName(). então this está ligado ao tom objeto e registra o valor tom (this.name é igual a tom aqui). O mesmo se aplica quando jerry.logName() é invocado.

Vimos que o JavaScript cria um ambiente para executar o código que escrevemos. Ele cuida da criação de memória para variáveis, funções, objetos e assim por diante no fase de criação. Finalmente, ele executa o código no fase de execução. Este ambiente especial é chamado de Execution Context.

Pode haver muitos desses ambientes (contextos de execução) em um aplicativo JavaScript. Cada contexto de execução opera independentemente dos outros.

Mas às vezes, podemos querer usar coisas de um contexto de execução em outro. É aqui que entra em jogo a vinculação explícita.

Na vinculação explícita, podemos chamar uma função com um objeto quando a função está fora do contexto de execução do objeto.

Existem três métodos muito especiais, call(), apply() e bind() que nos ajudam a obter uma vinculação explícita.

Como o JavaScript call() Método funciona

Com o call() método, o contexto com o qual a função deve ser chamada será passado como um parâmetro para o call(). Vamos ver como funciona com um exemplo:

let getName = function() {     console.log(this.name); } let user = {   name: 'Tapas',   address: 'Freecodecamp'   };getName.call(user);

Aqui o call() método é invocado em uma função chamada getName(). o getName() função apenas registros this.name. Mas o que é this aqui? Isso é determinado pelo que foi passado para o call() método.

Aqui, this irá ligar ao objeto de usuário porque passamos o usuário como um parâmetro para o call() método. então this.name deve registrar o valor da propriedade name do objeto de usuário, que é Tapas.

No exemplo acima, passamos apenas um argumento para call(). Mas também podemos passar vários argumentos para call(), como isso:

let getName = function(hobby1, hobby2) {     console.log(this.name + ' likes ' + hobby1 + ' , ' + hobby2); }let user = {   name: 'Tapas',   address: 'Bangalore'   };let hobbies = ['Swimming', 'Blogging']; getName.call(user, hobbies[0], hobbies[1]);

Aqui, passamos vários argumentos para o call() método. O primeiro argumento deve ser o contexto do objeto com o qual a função deve ser chamada. Outros parâmetros podem ser apenas valores a serem usados.

Aqui estou passando Natação e Blogging como dois parâmetros para o getName() função.

Você notou um ponto de dor aqui? No caso de um call(), os argumentos precisam ser passados ​​um a um – o que não é uma maneira inteligente de fazer as coisas! É aí que nosso próximo método, apply(), entra em cena.

Como o JavaScript apply() Método funciona

Esta maneira agitada de passar argumentos para o call() método pode ser resolvido por outro método alternativo chamado apply(). É exatamente o mesmo que call() mas permite que você passe os argumentos de maneira mais conveniente. Dar uma olhada:

let getName = function(hobby1, hobby2) {     console.log(this.name + ' likes ' + hobby1 + ' , ' + hobby2); } let user = {   name: 'Tapas',   address: 'Bangalore'   };let hobbies = ['Swimming', 'Blogging']; getName.apply(user, hobbies);

Aqui podemos passar uma série de argumentos, o que é muito mais conveniente do que passá-los um por um.

Dica: quando você tiver apenas um argumento de valor ou nenhum argumento de valor para passar, use call(). Quando você tem vários argumentos de valor para passar, use apply().

Como o JavaScript bind() Método funciona

o bind() método é semelhante ao call() método, mas com uma diferença. Ao contrário do call() método de chamar a função diretamente, bind() retorna uma função totalmente nova e podemos invocá-la em seu lugar.

let getName = function(hobby1, hobby2) {     console.log(this.name + ' likes ' + hobby1 + ' , ' + hobby2); }let user = {   name: 'Tapas',   address: 'Bangalore'   };let hobbies = ['Swimming', 'Blogging'];let newFn = getName.bind(user, hobbies[0], hobbies[1]); newFn();

Aqui o getName.bind() não invoca a função getName() diretamente. Ele retorna uma nova função, newFn e podemos invocá-lo como newFn().

UMA new palavra-chave é usada para criar um objeto da função do construtor.

let Cartoon = function(name, animal) {     this.name = name;     this.animal = animal;     this.log = function() {         console.log(this.name +  ' is a ' + this.animal);     } };

Você pode criar objetos usando o new palavra-chave como esta:

 let tom = new Cartoon('Tom', 'Cat'); let jerry = new Cartoon('Jerry', 'Mouse');

A nova regra de vinculação da função construtora afirma que, quando uma função é chamada com a nova palavra-chave, a palavra-chave this dentro da função se vincula ao novo objeto que está sendo construído.

Parece complexo? Ok, vamos decompô-lo. Pegue esta linha,

let tom = new Cartoon('Tom', 'Cat');

Aqui, a função Cartoon é invocada com o new palavra-chave. então this será vinculado ao novo objeto sendo criado aqui, que é tom.

Qual você acha que será a saída do código abaixo? O que é this ligando para aqui?

let sayName = function(name) {    console.log(this.name);};window.name="Tapas";sayName();

Se o this a palavra-chave não foi resolvida com nenhuma das ligações, implicit, explicit ou new, então o this está ligado ao window(global) objeto.

No entanto, há uma exceção. JavaScript modo estrito não permite essa ligação padrão.

"use strict";function myFunction() {  return this;}

No caso acima, this é undefined.

Em manipuladores de eventos HTML, this liga-se aos elementos HTML que recebem o evento.

<button onclick="console.log(this)">Click Me!</button>

Este é o registro de saída no console quando você clica no botão:

"<button onclick='console.log(this)'>Click Me!</button>"

Você pode alterar o estilo do botão usando o this palavra-chave, como esta:

<button onclick="this.style.color="teal"">Click Me!</button>

Mas esteja atento ao chamar uma função ao clicar no botão e usar this dentro dessa função.

<button onclick="changeColor()">Click Me!</button>

e o JavaScript:

function changeColor() {  this.style.color="teal";}

O código acima não funcionará conforme o esperado. Como vimos na Regra 4, aqui this será vinculado ao objeto global (no modo ‘não estrito’) onde não há estilo objeto para definir a cor.

Para resumir,

  • No caso de ligação implícita, this vincula-se ao objeto à esquerda do operador ponto (.).
  • No caso de ligação explícita, podemos chamar uma função com um objeto quando a função está fora do contexto de execução do objeto. Os métodos call(), apply(), e bind() desempenham um grande papel aqui.
  • Quando uma função é chamada com o new palavra-chave, o this A palavra-chave dentro da função se liga ao novo objeto que está sendo construído.
  • Quando o this a palavra-chave não foi resolvida com nenhuma das ligações, implicit, explicit ou new, então this está ligado ao window(global) objeto. No modo estrito do JavaScript, this será indefinido.
  • Em manipuladores de eventos HTML, this liga-se aos elementos HTML que recebem o evento.

Existe mais um caso onde this se comporta de maneira diferente, como com ES6 arrow functions. Veremos isso em um artigo futuro.

Espero que você tenha achado este artigo esclarecedor. Você pode gostar,

Se este artigo foi útil, compartilhe-o para que outras pessoas também possam lê-lo. Você pode me @ no Twitter (@tapasadhikary) com comentários ou fique à vontade para me seguir.



[ad_2]

Fonte