este artigo foi originalmente escrito para DigitalOcean.
this
palavra-chave é um conceito muito importante em JavaScript, e também um particularmente confuso, um tanto de novas desenvolvedores e aqueles que têm experiência em outras linguagens de programação. Em JavaScript, this
é uma referência a um objeto., O objeto this
refere pode variar, implicitamente com base em se ele é global, em um objeto ou em um construtor, e pode variar também, explicitamente, com base na utilização de Function
protótipo métodos de bind
call
e apply
.
embora this
é um pouco de um tópico complexo, também é um que aparece assim que você começa a escrever seus primeiros programas JavaScript., Quer esteja a tentar aceder a um elemento ou evento no modelo de objecto do documento (DOM), a criar classes para escrever no estilo de programação orientado a objectos, ou a usar as propriedades e métodos dos objectos regulares, irá encontrar this
.
neste artigo, você vai aprender o que this
refere-se implicitamente com base no contexto, e você vai aprender como usar o bind
call
e apply
métodos para determinar explicitamente o valor de this
.,
Implícito Contexto
Existem quatro principais contextos em que o valor de this
pode ser implicitamente inferida:
- o contexto global
- como um método de dentro de um objeto
- como um construtor em uma função ou classe
- como um DOM manipulador de eventos
Global
No contexto global, this
refere-se ao objeto global. Quando você está trabalhando em um navegador, o contexto global é window
. Quando estás a trabalhar no nó.js, o contexto global é global
.,
Nota: Se você ainda não está familiarizado com o conceito de escopo em JavaScript, por favor reveja as variáveis de compreensão, escopo e listagem em JavaScript.
para os exemplos, você irá praticar o código na consola de ferramentas de desenvolvimento do navegador. Leia Como usar a consola de desenvolvimento de JavaScript se você não estiver familiarizado com a execução de código de JavaScript no navegador.se registar o valor de this
sem qualquer outro código, verá a que objecto this
se refere.,
console.log(this)
Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}
Você pode ver que this
é window
, que é o objeto global de um navegador.
na compreensão de variáveis, escopo e içar em JavaScript, você aprendeu que as funções têm seu próprio contexto para variáveis. Você pode ser tentado a pensar que this
seguiria as mesmas regras dentro de uma função, mas não segue. Uma função de nível superior ainda manterá a this
referência do objeto global.,
Você escrever uma função de nível superior, ou uma função que não está associado a qualquer objeto, assim:
function printThis() { console.log(this)}printThis()
Window {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}
Mesmo dentro de uma função, this
refere-se ainda a window
, ou objeto global.
no Entanto, quando utilizar de modo estrito, o contexto de this
dentro de uma função no contexto global será undefined
.,
'use strict'function printThis() { console.log(this)}printThis()
undefined
em Geral, é mais seguro usar o modo estrito, para reduzir a probabilidade de this
tendo um inesperado escopo. Raramente alguém vai querer se referir ao objeto usandothis
.
Para mais informações sobre o modo estrito e as mudanças que ele faz em relação a erros e segurança, leia a documentação do modo estrito no MDN.,
Um Método de Objeto
Um método é uma função em um objeto, ou uma tarefa que um objeto pode executar. Um método usa this
para se referir às propriedades do objeto.
"The United States of America was founded in 1776."
neste exemplo, this
é o mesmo que america
.
em um objeto aninhado, this
refere-se ao escopo atual do objeto do método. No exemplo a seguir, this.symbol
dentro de details
objeto refere-se a details.symbol
.,
"The symbol is the eagle and the currency is USD."
outra maneira de pensar sobre isso é que this
refere-se ao objeto do lado esquerdo do ponto ao chamar um método.
Um construtor de funções
quando você usa o new
palavra-chave, ele cria uma instância de uma função ou classe de construtor. Construtores de funções foram a maneira padrão de inicializar um objeto definido pelo Usuário antes que o sintaxe foi introduzida na atualização ECMAScript 2015 para JavaScript., Na compreensão de Classes em JavaScript, você vai aprender como criar um construtor de funções e um construtor de classe equivalente.
"The United States of America was founded in 1776."
neste contexto, this
agora está vinculado a instância de Country
, que está contido no america
constante.
Um construtor de classes
um construtor de uma classe age da mesma forma que um construtor em uma função. Leia mais sobre as semelhanças e diferenças entre construtores de funções e classes ES6 na compreensão de Classes em JavaScript.,
this
describe
método refere-se à instância de Country
, que é o america
.
"The United States of America was founded in 1776."
a DOM Event Handler
no navegador, existe um especial this
contexto para os responsáveis por eventos. In an event handler called by addEventListener
, this
will refer to event.currentTarget
., Mais frequentemente do que não, os desenvolvedores simplesmente irá usar event.target
ou event.currentTarget
conforme necessário para acessar os elementos no DOM, mas uma vez que o this
alterações de referência neste contexto, é importante saber.
no exemplo a seguir, vamos criar um botão, Adicionar texto a ele, e adicioná-lo ao DOM. Quando registramos o valor de this
dentro do manipulador de eventos, ele imprimirá o alvo.,
<button>Click me</button>
Depois de colar isto no seu navegador, irá ver um botão adicionado à página que diz “Carregue em mim”. Se carregar no botão, irá ver <button>Click me</button>
aparecer na sua consola, enquanto se carregar no botão regista o elemento, que é o botão em si. Portanto, como você pode ver, this
refere-se ao elemento alvo, que é o elemento ao qual adicionamos um ouvinte de eventos.,
Contexto Explícito
Em todos os exemplos anteriores, o valor de this
foi determinado pelo seu contexto, seja ela global, em um objeto, em um construídos função ou classe, ou em um DOM de manipulador de eventos. No entanto, o uso de call
apply
, ou bind
, você pode determinar explicitamente o que this
deve referir-se.,
é difícil definir exatamente quando usar call
apply
, ou bind
, pois vai depender do contexto do seu programa. bind
pode ser particularmente útil quando você quer usar eventos para acessar propriedades de uma classe dentro de outra classe. Por exemplo, se você fosse escrever um jogo simples, você poderia separar a interface do Usuário e o E/S em uma classe, e a lógica do jogo e o estado em outra., Uma vez que a lógica do jogo precisaria acessar a entrada, como a tecla press e o clique, você gostaria de bind
os eventos para acessar o this
valor da classe lógica do jogo.
O importante é saber como determinar o objeto this
refere-se para, o que você pode fazer, implicitamente, com o que você aprendeu nas seções anteriores, ou explicitamente, com os três métodos que você vai aprender o seguinte.,
Call and Apply
call
andapply
são muito semelhantes—invocam uma função com um ID especificado
contexto, e argumentos opcionais. A única diferença entre call
e apply
é que call
requer os argumentos a serem passados em um por um, e apply
leva a argumentos como uma matriz.,
neste exemplo, vamos criar um objeto e criar uma função que faz referência this
, mas nenhuma tag this
contexto.
"undefined was written by undefined"
Desde summary
e book
tem conexão, invocando summary
por si só impressão undefined
, como é olhar para as propriedades no objeto global.,
Nota: se Tentar fazer isso no modo estrito, o resultado seria
Uncaught TypeError: Cannot read property 'title' of undefined
this
si só, seriaundefined
.
no Entanto, você pode usar call
e apply
para chamar o this
contexto book
na função.,
summary.call(book)// or:summary.apply(book)
"Brave New World was written by Aldous Huxley."
agora, Há uma conexão entre book
e summary
quando esses métodos são aplicados. Vamos confirmar exatamente o que é this
.
function printThis() { console.log(this)}printThis.call(book)// or:whatIsThis.apply(book)
{title: "Brave New World", author: "Aldous Huxley"}
neste caso, this
na verdade torna-se o objeto passado como argumento.
This is how call
andapply
are the same, but there is one small difference., Além de ser capaz de passar o contexto this
como o primeiro argumento, você também pode passar argumentos adicionais através.
function longerSummary(genre, year) { console.log( `${this.title} was written by ${this.author}. It is a ${genre} novel written in ${year}.`, )}
Com call
cada valor adicional que você deseja passar é enviado como um argumento adicional.,
longerSummary.call(book, 'dystopian', 1932)
"Brave New World was written by Aldous Huxley. It is a dystopian novel written in 1932."
Se você tentar enviar o exato mesmo argumentos com apply
, isto é o que acontece:
longerSummary.apply(book, 'dystopian', 1932)
Uncaught TypeError: CreateListFromArrayLike called on non-object at <anonymous>:1:15
em Vez disso, para o apply
, você tem que passar todos os argumentos em uma matriz.
longerSummary.apply(book, )
"Brave New World was written by Aldous Huxley. It is a dystopian novel written in 1932."
A diferença entre passar os argumentos individualmente ou em uma matriz é sutil, mas é importante estar ciente de., Pode ser mais simples e conveniente usar apply
, uma vez que não seria necessário alterar a chamada de função se alguns detalhes do parâmetro mudassem.
Bind
Os call
e apply
são de um tempo de uso de métodos de se chamar o método com o this
contexto, é tê-lo, mas a função original permanecerá inalterado.,
às Vezes, você pode precisar usar um método mais e mais com o this
contexto de outro objeto, e nesse caso você pode usar o bind
método para criar uma nova função com um explicitamente vinculado this
.
const braveNewWorldSummary = summary.bind(book)braveNewWorldSummary()
"Brave New World was written by Aldous Huxley"
neste exemplo, a cada vez que você chamar braveNewWorldSummary
, ele sempre irá retornar o original this
valor vinculado a ele., A tentativa de ligar um novo id
contexto a ele irá falhar, por isso você pode sempre confiar numa função vinculada para devolver o valor this
valor que você espera.
Embora este exemplo tenta ligar braveNewWorldSummary
mais uma vez, ele mantém o original this
o contexto da primeira vez em que foi ligado.
funções de seta
funções de seta não têm o seu próprio this
ligação. Em vez disso, eles vão para o próximo nível de execução.,
pode ser útil usar a função seta nos casos em que você realmente deseja this
para se referir ao contexto exterior. Por exemplo, se você tivesse um ouvinte de eventos dentro de uma classe, você provavelmente iria querer this
para se referir a algum valor na classe.
neste exemplo, você irá criar e adicionar o botão ao DOM como antes, mas a classe terá um ouvinte de eventos que irá alterar o valor de texto do botão quando carregar nele.
Se carregar no botão, o conteúdo do texto irá mudar para o valor de ., Se você não tivesse usado uma seta função aqui, this
deve ser igual a event.currentTarget
, e você não seria capaz de usá-lo para acessar um valor dentro da classe, sem explicitamente enlace. Esta tática é frequentemente usada em métodos de classe em frameworks como Reat.
Conclusão
neste artigo, você aprendeu sobre this
em JavaScript, e os diferentes valores que ele pode ter com base na implícito de tempo de execução obrigatória, e explícita a ligação através de bind
call
e apply
., Você também aprendeu sobre como a falta dethis
ligação em funções de seta pode ser usado para se referir a um contexto diferente. Com este conhecimento, você deve ser capaz de determinar o valor de this
em seus programas.