Percebi que não parece haver uma explicação clara sobre qual é a this
palavra-chave e como ela é correta (e incorretamente) usada no JavaScript no site Stack Overflow.
Testemunhei um comportamento muito estranho e não consegui entender por que ocorreu.
Como this
funciona e quando deve ser usado?
javascript
this
Maxim Gershkovich
fonte
fonte
this
peter.michaux.ca/articles/javascript-widgets-without-thisthis
palavra-chave: rainsoft.io/gentle-explanation-of-this-in-javascriptRespostas:
Eu recomendo ler o artigo de Mike West Scope em JavaScript ( espelho ) primeiro. É uma introdução excelente e amigável aos conceitos
this
e cadeias de escopo em JavaScript.Depois que você começa a se acostumar
this
, as regras são bem simples. O padrão ECMAScript 5.1 definethis
:ThisBinding é algo que o intérprete JavaScript mantém ao avaliar o código JavaScript, como um registro especial da CPU que mantém uma referência a um objeto. O intérprete atualiza o ThisBinding sempre que estabelecer um contexto de execução em um dos três casos diferentes:
1. Contexto inicial de execução global
Este é o caso do código JavaScript que é avaliado no nível superior, por exemplo, quando diretamente dentro de um
<script>
:Ao avaliar o código no contexto inicial de execução global, ThisBinding é definido como o objeto global
window
( §10.4.1.1 ).Introduzir código de avaliação
… Por uma chamada direta para
eval()
ThisBinding permanece inalterada; é o mesmo valor que o ThisBinding do contexto de execução de chamada ( §10.4.2 (2) (a)).… Se não por uma chamada direta para
eval()
ThisBinding estiver definido como o objeto global como se estivesse sendo executado no contexto de execução global inicial ( §10.4.2 (1)).
§15.1.2.1.1 define o que é uma chamada direta
eval()
. Basicamente,eval(...)
é uma chamada direta, enquanto algo como(0, eval)(...)
ouvar indirectEval = eval; indirectEval(...);
é uma chamada indiretaeval()
. Veja a resposta de chuckj para (1, eval) ('this') vs eval ('this') em JavaScript? e ECMA-262-5 de Dmitry Soshnikov em detalhes. Capítulo 2. Modo Estrito. para quando você pode usar umaeval()
chamada indireta .Introduzir código de função
Isso ocorre ao chamar uma função. Se uma função é chamada em um objeto, como em
obj.myMethod()
ou equivalenteobj["myMethod"]()
, ThisBinding é definido como o objeto (obj
no exemplo; §13.2.1 ). Na maioria dos outros casos, ThisBinding é definido como o objeto global ( §10.4.3 ).O motivo para escrever "na maioria dos outros casos" é porque existem oito funções internas do ECMAScript 5 que permitem que ThisBinding seja especificado na lista de argumentos. Essas funções especiais usam o chamado
thisArg
que se torna o ThisBinding ao chamar a função ( §10.4.3 ).Essas funções internas especiais são:
Function.prototype.apply( thisArg, argArray )
Function.prototype.call( thisArg [ , arg1 [ , arg2, ... ] ] )
Function.prototype.bind( thisArg [ , arg1 [ , arg2, ... ] ] )
Array.prototype.every( callbackfn [ , thisArg ] )
Array.prototype.some( callbackfn [ , thisArg ] )
Array.prototype.forEach( callbackfn [ , thisArg ] )
Array.prototype.map( callbackfn [ , thisArg ] )
Array.prototype.filter( callbackfn [ , thisArg ] )
No caso das
Function.prototype
funções, elas são chamadas em um objeto de função, mas, em vez de definir ThisBinding para o objeto de função, ThisBinding é definido comothisArg
.No caso das
Array.prototype
funções, o dadocallbackfn
é chamado em um contexto de execução em que ThisBinding está definido comothisArg
se for fornecido; caso contrário, para o objeto global.Essas são as regras para JavaScript simples. Ao começar a usar bibliotecas JavaScript (por exemplo, jQuery), você pode achar que determinadas funções da biblioteca manipulam o valor de
this
. Os desenvolvedores dessas bibliotecas JavaScript fazem isso porque tendem a suportar os casos de uso mais comuns, e os usuários da biblioteca geralmente acham esse comportamento mais conveniente. Ao transmitir funções de retorno de chamada referentesthis
a funções de biblioteca, você deve consultar a documentação para obter garantias sobre qual é o valorthis
quando a função é chamada.Se você está se perguntando como uma biblioteca JavaScript manipula o valor de
this
, a biblioteca está simplesmente usando uma das funções JavaScript incorporadas que aceitam athisArg
. Você também pode escrever sua própria função usando uma função de retorno de chamada ethisArg
:Há um caso especial que ainda não mencionei. Ao construir um novo objeto por meio do
new
operador, o interpretador JavaScript cria um novo objeto vazio, define algumas propriedades internas e, em seguida, chama a função construtora no novo objeto. Assim, quando uma função é chamada em um contexto de construtor, o valor dethis
é o novo objeto que o intérprete criou:Funções de seta
As funções de seta (introduzidas no ECMA6) alteram o escopo de
this
. Veja a pergunta canônica existente, Função da seta versus declaração / expressões da função: Eles são equivalentes / intercambiáveis? Para maiores informações. Mas em suma:Apenas por diversão, teste sua compreensão com alguns exemplos
Para revelar as respostas, passe o mouse sobre as caixas cinza claro.
Qual é o valor de
this
na linha marcada? Por quê?Qual é o valor da
this
linha marcada quandoobj.staticFunction()
é executado? Por quê?Qual é o valor de
this
na linha marcada? Por quê?Qual é o valor de
this
na linha marcada? Por quê?Qual é o valor de
this
na linha marcada? Por quê?fonte
setTimeout
exemplo tem umthis
dewindow(global)
.A
this
palavra-chave se comporta de maneira diferente no JavaScript em comparação com outros idiomas. Nos idiomas orientados a objetos, athis
palavra - chave refere-se à instância atual da classe. Em JavaScript, o valor dethis
é determinado pelo contexto de chamada de function (context.function()
) e onde é chamado.1. Quando usado no contexto global
Quando você usa
this
no contexto global, ele é vinculado ao objeto global (window
no navegador)Quando você usa
this
dentro de uma função definida no contexto global,this
ainda está vinculado ao objeto global, pois a função é realmente transformada em um método de contexto global.Acima
f1
é feito um método de objeto global. Assim, também podemos chamá-lo nowindow
objeto da seguinte maneira:2. Quando usado dentro do método de objeto
Quando você usa a
this
palavra-chave dentro de um método de objeto,this
é vinculado ao objeto envolvente "imediato".Acima, coloquei a palavra imediato entre aspas duplas. É importante ressaltar que, se você aninhar o objeto dentro de outro objeto,
this
será vinculado ao pai imediato.Mesmo se você adicionar uma função explicitamente ao objeto como método, ela ainda segue as regras acima, que
this
ainda apontam para o objeto pai imediato.3. Ao chamar a função sem contexto
Quando você usa a
this
função interna que é chamada sem nenhum contexto (ou seja, não está em nenhum objeto), ela é vinculada ao objeto global (window
no navegador) (mesmo que a função esteja definida dentro do objeto).Tentando tudo com funções
Também podemos tentar os pontos acima com funções. No entanto, existem algumas diferenças.
this
. para especificá-los.new
operator.Abaixo, tentei todas as coisas que fizemos com o Object e
this
acima, mas primeiro criando a função em vez de escrever diretamente um objeto.4. Quando usado dentro da função construtora .
Quando a função é usada como construtor (ou seja, é chamada com
new
palavra - chave), othis
corpo interno da função aponta para o novo objeto que está sendo construído.5. Quando usado dentro da função definida na cadeia de protótipos
Se o método estiver na cadeia de protótipos de um objeto,
this
dentro desse método se refere ao objeto em que o método foi chamado, como se o método estivesse definido no objeto.6. Funções internas de chamada (), apply () e bind ()
Function.prototype
.this
que será usado enquanto a função estiver sendo executada. Eles também levam todos os parâmetros a serem passados para a função original quando ela é chamada.fun.apply(obj1 [, argsArray])
Defineobj1
como o valor dethis
insidefun()
e chamafun()
elementos passantes deargsArray
como seus argumentos.fun.call(obj1 [, arg1 [, arg2 [,arg3 [, ...]]]])
- Defineobj1
como o valor dethis
dentrofun()
e chamafun()
passandoarg1, arg2, arg3, ...
como seus argumentos.fun.bind(obj1 [, arg1 [, arg2 [,arg3 [, ...]]]])
- Retorna a referência à funçãofun
comthis
diversão interna vinculada aobj1
e parâmetros defun
vinculada aos parâmetros especificadosarg1, arg2, arg3,...
.apply
,call
ebind
deve ter se tornado aparente.apply
permite especificar os argumentos para funcionar como objeto de matriz, ou seja, um objeto com umalength
propriedade numérica e propriedades inteiras não negativas correspondentes. Considerando quecall
permite especificar os argumentos para a função diretamente. Ambosapply
ecall
imediatamente chama a função no contexto especificado e com os argumentos especificados. Por outro lado,bind
simplesmente retorna a função vinculada aothis
valor especificado e aos argumentos. Podemos capturar a referência a essa função retornada atribuindo-a a uma variável e, posteriormente, podemos chamá-la a qualquer momento.7.
this
manipuladores de eventos internosthis
função de manipulação de eventos diretamente interna refere-se ao elemento correspondente. Essa atribuição direta de função pode ser feita usando oaddeventListener
método ou através dos métodos tradicionais de registro de eventos, comoonclick
.this
diretamente dentro da propriedade de evento (like<button onclick="...this..." >
) do elemento, ela se refere ao elementothis
indireto de outra função chamada dentro da função de manipulação de eventos ou propriedade do evento é resolvido para o objeto globalwindow
.attachEvent
. Em vez de atribuir a função ao manipulador de eventos (e assim tornar o método de função do elemento), ele chama a função no evento (efetivamente chamando-o no contexto global).Eu recomendo tentar melhor isso no JSFiddle .
8.
this
na função de seta ES6Em uma função de seta,
this
comportará-se como variáveis comuns: será herdada de seu escopo lexical. A funçãothis
, onde a função de seta é definida, será a função de setathis
.Portanto, esse é o mesmo comportamento que:
Veja o seguinte código:
fonte
this
não é definido pela chamada. Como o código não está no modo estrito, o valor dethis
deve sempre ser um objeto, por padrão, para o objeto global. E, de fato, foi por isso que pensei que poderíamos fazer chamadas diretamentewindow.f1()
, de modo que o meiof1()
já está anexado aowindow
objeto, antes da invocação. Estou entendendo errado?window.fn
, o que não é. o padrão é o objeto global porque nenhuma referência base foi usada na chamada, não por onde a função está definida (portanto, isso ainda é definido pelo modo como a função foi chamada). Se você chamá-lo explicitamente usandowindow.fn
, está configurando isso para janela . Mesmo resultado, uma maneira diferente de fazer isso. :-)Javascript
this
Chamada de Função Simples
Considere a seguinte função:
Observe que estamos executando isso no modo normal, ou seja, o modo estrito não é usado.
Ao executar em um navegador, o valor de
this
seria registrado comowindow
. Isso ocorre porquewindow
é a variável global no escopo de um navegador da web.Se você executar esse mesmo pedaço de código em um ambiente como o node.js,
this
consulte a variável global no seu aplicativo.Agora, se executarmos isso no modo estrito adicionando a instrução
"use strict";
ao início da declaração da função,this
não se referirá mais à variável global em nenhum dos ambientes. Isso é feito para evitar confusões no modo estrito.this
nesse caso, apenas registrariaundefined
, porque é isso que é, não está definido.Nos seguintes casos, veríamos como manipular o valor de
this
.Chamando uma função em um objeto
Existem diferentes maneiras de fazer isso. Se você tem chamado métodos nativos em Javascript como
forEach
eslice
, você já deve saber que athis
variável, nesse caso, refere-se aoObject
em que você chamou essa função (Note-se que em javascript, quase tudo é umObject
, incluindoArray
s eFunction
s). Pegue o seguinte código, por exemplo.Se um
Object
contém uma propriedade que contém aFunction
, a propriedade é chamada de método. Este método, quando chamado, sempre terá suathis
variável definida como aObject
qual está associada. Isso vale para os modos estrito e não estrito.Observe que se um método for armazenado (ou melhor, copiado) em outra variável, a referência a
this
não será mais preservada na nova variável. Por exemplo:Considerando um cenário mais comumente prático:
A
new
palavra-chaveConsidere uma função construtora em Javascript:
Como é que isso funciona? Bem, vamos ver o que acontece quando usamos a
new
palavra - chave.new
palavra - chave inicializaria imediatamente umObject
tipoPerson
.Object
tem seu construtor definido comoPerson
. Além disso, observe quetypeof awal
retornariaObject
apenas.Object
seria atribuído o protótipo dePerson.prototype
. Isso significa que qualquer método ou propriedade noPerson
protótipo estaria disponível para todas as instâncias dePerson
, inclusiveawal
.Person
si agora é invocada;this
sendo uma referência ao objeto recém-construídoawal
.Bem direto, não é?
Observe que a especificação oficial do ECMAScript em nenhum lugar afirma que esses tipos de funções são reais
constructor
. São apenas funções normais enew
podem ser usadas em qualquer função. É que nós os usamos como tal e, portanto, os chamamos apenas como tal.Chamando funções em Funções:
call
eapply
Então sim, como
function
s também sãoObjects
(e de fato variáveis de primeira classe em Javascript), até as funções têm métodos que são ... bem, elas próprias.Todas as funções herdam do global
Function
, e dois de seus muitos métodos sãocall
eapply
, e ambos podem ser usados para manipular o valor dathis
função na qual são chamados.Este é um exemplo típico de uso
call
. Basicamente, pega o primeiro parâmetro e definethis
a funçãofoo
como referênciathisArg
. Todos os outros parâmetros passadoscall
são passados para a funçãofoo
como argumentos.Portanto, o código acima fará logon
{myObj: "is cool"}, [1, 2, 3]
no console. Maneira bastante agradável de alterar o valor dethis
em qualquer função.apply
é quase o mesmo quecall
aceitar que são necessários apenas dois parâmetros:thisArg
e uma matriz que contém os argumentos a serem passados para a função. Portanto, acall
chamada acima pode ser traduzida paraapply
:Observe que
call
eapply
pode substituir o valor dathis
chamada de método definido por ponto que discutimos no segundo marcador. Simples o suficiente :)Apresentando ....
bind
!bind
é irmão decall
eapply
. É também um método herdado por todas as funções doFunction
construtor global em Javascript. A diferença entrebind
ecall
/apply
é que amboscall
eapply
realmente chamarão a função.bind
, por outro lado, retorna uma nova função comthisArg
earguments
pré-configurada. Vamos dar um exemplo para entender melhor isso:Veja a diferença entre os três? É sutil, mas eles são usados de maneira diferente. Like
call
eapply
,bind
também substituem o valor dethis
set pela chamada do método dot.Observe também que nenhuma dessas três funções altera a função original.
call
eapply
retornaria o valor das funções recém-construídas, enquantobind
retornaria a própria função recém-construída, pronta para ser chamada.Coisas extras, copie isso
Às vezes, você não gosta do fato de que
this
muda com o escopo, especialmente o escopo aninhado. Veja o exemplo a seguir.No código acima, vemos que o valor de
this
mudou com o escopo aninhado, mas queríamos o valor dothis
escopo original. Então nós 'copiado'this
athat
e usou a copiar em vez dethis
. Inteligente, não é?Índice:
this
por padrão?new
palavra - chave?this
comcall
eapply
?bind
.this
para resolver problemas de escopo aninhado.fonte
"this" tem tudo a ver com escopo. Toda função tem seu próprio escopo e, como tudo em JS é um objeto, mesmo uma função pode armazenar alguns valores em si mesma usando "this". OOP 101 ensina que "isso" é aplicável apenas a instâncias de um objeto. Portanto, sempre que uma função é executada, uma nova "instância" dessa função tem um novo significado de "this".
A maioria das pessoas fica confusa quando tenta usar "this" dentro das funções de fechamento anônimo, como:
Então aqui, dentro de cada (), "this" não contém o "valor" que você espera (de
acima dele). Portanto, para superar esse problema (sem trocadilhos), um desenvolvedor pode:Experimente; você começará a gostar desse padrão de programação
fonte
this
palavra-chave não tem nada a ver com escopo. Além disso, também tem um significado em funções que não são propriedades de objetos.this
não é tudo sobre escopo. É tudo sobre o contexto de execução, que não é a mesma coisa que escopo. O JavaScript tem escopo lexical (o escopo é determinado pela localização do código), masthis
é determinado pela maneira como a função que o contém é invocada - e não onde essa função está.Desde que esse tópico aumentou, compilei alguns pontos para leitores novos no
this
tópico.Como é
this
determinado o valor ?Usamos essa semelhante à maneira como usamos pronomes nas línguas naturais como o Inglês: “John está correndo rápido, porque ele está tentando pegar o trem.” Em vez disso, poderíamos ter escrito "... John está tentando pegar o trem".
this
não recebe um valor até que um objeto chame a função em que está definido. No escopo global, todas as variáveis e funções globais são definidas nowindow
objeto. Portanto,this
em uma função global se refere (e tem o valor de) aowindow
objeto global .Quando
use strict
,this
nas funções globais e anônimas que não estão vinculadas a nenhum objeto, mantém um valor deundefined
.A
this
palavra-chave é mais incompreendida quando: 1) emprestamos um método que usathis
, 2) atribuímos um método que usathis
a uma variável, 3) uma função que usathis
é passada como uma função de retorno de chamada e 4)this
é usada dentro de um fechamento - uma função interna. 2)O que guarda o futuro
Definidas no ECMA Script 6 , as funções de seta adotam a
this
ligação do escopo anexo (função ou global).Embora as funções de seta forneçam uma alternativa ao uso
bind()
, é importante observar que elas estão desativando othis
mecanismo tradicional em favor de um escopo lexical mais amplamente compreendido. (1)Referências:
fonte
this
em JavaScript sempre se refere ao 'proprietário' da função que está sendo executada .Se nenhum proprietário explícito for definido, o principal proprietário, o objeto de janela, será referenciado.
Então se eu fiz
element.onclick = someKindOfFunction;
this
se referiria ao objeto elemento. Mas tenha cuidado, muitas pessoas cometem esse erro.<element onclick="someKindOfFunction()">
Neste último caso, você apenas faz referência à função, não a entrega ao elemento. Portanto,
this
fará referência ao objeto da janela.fonte
Todo contexto de execução em javascript possui um parâmetro this que é definido por:
eval
Você pode definir o valor disso usando
func.call
,func.apply
oufunc.bind
.Por padrão, e o que confunde a maioria dos iniciantes, quando um ouvinte é chamado depois que um evento é gerado em um elemento DOM, esse valor da função é o elemento DOM.
O jQuery torna isso trivial mudar com o jQuery.proxy.
fonte
this
em Javascript é que é não uma propriedade intrínseca da própria função, mas sim um artefato da maneira como a função é invocada.func.call
,func.bind
etc. - Sushilthis
se não referenciar o escopo de uma função.this
fará referência a um objeto específico (ou possivelmenteundefined
), que, como você disse, pode ser alterado usando.call()
ou.apply()
. O escopo de uma função é (essencialmente, quando simplificado) a quais variáveis ele tem acesso, e isso depende inteiramente de onde a função é declarada e não pode ser alterada.this
e o escopo não tem nada a ver um com o outro no ES5 e antes (por exemplo, quando esta resposta foi escrita). No ES2015 (também conhecido como ES6),this
e o escopo estão relacionados de uma maneira bastante mínima: as funções de seta wrt (othis
em uma seta é herdada de seu escopo anexo), masthis
nunca se refere a um escopo.Aqui está uma boa fonte de
this
inJavaScript
.Aqui está o resumo:
global isso
Em um navegador, no escopo global,
this
é owindow
objetoAo
node
usar a repl,this
é o namespace principal. Você pode se referir a ele comoglobal
.Na
node
execução de um script,this
no escopo global começa como um objeto vazio. Não é o mesmo queglobal
funcionar isso
Exceto no caso de manipuladores de eventos DOM ou quando um
thisArg
é fornecido (veja mais abaixo), tanto no nó quanto em um navegador, usandothis
uma função que não é chamada comnew
referência no escopo global…Se você usar
use strict;
, nesse casothis
seráundefined
Se você chamar uma função com
new
othis
será um novo contexto, ela não fará referência ao globalthis
.As funções que você cria se tornam objetos de função. Eles obtêm automaticamente uma
prototype
propriedade especial , à qual você pode atribuir valores. Quando você cria uma instância chamando sua função comnew
você obtém acesso aos valores que você atribuiu àprototype
propriedade. Você acessa esses valores usandothis
.Geralmente, é um erro atribuir matrizes ou objetos no
prototype
. Se você deseja que as instâncias tenham suas próprias matrizes, crie-as na função, não no protótipo.Você pode usar
this
em qualquer função de um objeto para se referir a outras propriedades desse objeto. Não é o mesmo que uma instância criada comnew
.Em um manipulador de eventos HTML DOM,
this
é sempre uma referência ao elemento DOM ao qual o evento foi anexadoA menos que você seja
bind
o contextoAtributos HTML internos nos quais você pode colocar JavaScript,
this
é uma referência ao elemento.Você pode usar
eval
para acessarthis
.Você pode usar
with
para adicionarthis
ao escopo atual a leitura e gravação de valoresthis
sem consultarthis
explicitamente.o jQuery, em muitos lugares, se
this
refere a um elemento DOM.fonte
Daniel, explicação incrível! Algumas palavras nesta e boa lista de
this
ponteiros de contexto de execução no caso de manipuladores de eventos.Em duas palavras,
this
no JavaScript, aponta o objeto de quem (ou de cujo contexto de execução) a função atual foi executada e é sempre somente leitura, você não pode defini-la de qualquer maneira (essa tentativa terminará com 'Mão esquerda inválida lado na mensagem de atribuição.Para manipuladores de eventos: os manipuladores de eventos em linha, como, por exemplo
<element onclick="foo">
, substituem quaisquer outros manipuladores anexados anteriormente e antes, portanto, tenha cuidado e é melhor evitar a delegação de eventos inline. E obrigado a Zara Alaverdyan, que me inspirou a esta lista de exemplos através de um debate dissidente :)el.onclick = foo; // in the foo - obj
el.onclick = function () {this.style.color = '#fff';} // obj
el.onclick = function() {doSomething();} // In the doSomething - Window
el.addEventListener('click',foo,false) // in the foo - obj
el.attachEvent('onclick, function () { // this }') // window, all the compliance to IE :)
<button onclick="this.style.color = '#fff';"> // obj
<button onclick="foo"> // In the foo - window, but you can <button onclick="foo(this)">
fonte
Há muita confusão sobre como "essa palavra-chave " é interpretada em JavaScript. Esperemos que este artigo repouse todos aqueles que descansam de uma vez por todas. E muito mais. Por favor, leia o artigo inteiro com atenção. Esteja avisado de que este artigo é longo.
Independentemente do contexto em que é usado, "this" sempre faz referência ao "objeto atual" em Javascript. No entanto, qual é o "objeto atual" difere de acordo com o contexto . O contexto pode ser exatamente 1 dos 6 a seguir:
A seguir, descreve cada um desses contextos, um por um:
Contexto Global (isto é, Fora de todas as funções):
Fora de todas as funções (isto é, no contexto global), o "objeto atual" (e, portanto, o valor de "isto" ) é sempre o objeto "janela" dos navegadores.
Chamada interna direta de "Função não vinculada" :
Dentro de uma chamada direta de "Função não vinculada", o objeto que chamou a chamada de função se torna o "objeto atual" (e, portanto, o valor de "this" ). Se uma função é chamada sem um objeto atual explícito , o objeto atual é o objeto "window" (para o modo não estrito) ou indefinido (para o modo estrito). Qualquer função (ou variável) definida no Contexto Global torna-se automaticamente uma propriedade do objeto "janela". Por exemplo, suponha que a função seja definida no Contexto Global como
torna-se propriedade do objeto de janela, como se você o tivesse definido como
No "Modo não estrito", chamar / chamar esta função diretamente por meio de "UserDefinedFunction ()" a chamará automaticamente como "window.UserDefinedFunction ()" making "window" como o "objeto atual" (e, portanto, o valor de " " ) em " UserDefinedFunction ". Invocar esta função no" Modo Não Rigoroso "resultará nos seguintes
Em "modo estrito", chamando / Invocando a função diretamente através de "UserDefinedFunction ()" irá "NÃO" automaticamente chamar / invocá-la como "window.UserDefinedFunction ()" .Hence o "objeto atual" (e o valor de "isto" ) em "UserDefinedFunction" será indefinido . A invocação desta função no "Modo estrito" resultará nos seguintes
No entanto, invocá-lo explicitamente usando o objeto window resultará nas seguintes
Vejamos outro exemplo. Por favor, olhe o código a seguir
No exemplo acima, vemos que quando "UserDefinedFunction" foi chamado por meio de o1 , "this" assume o valor de o1 e o valor de suas propriedades "a" e "b" são exibidos. O valor de "c" e "d" foi mostrado como indefinido, pois o1 não define essas propriedades
Da mesma forma, quando "UserDefinedFunction" foi invocado através o2 , "este" toma o valor de O2 e o valor das suas propriedades de "c" e "d" obter displayed.The valor de "a" e "b" foram mostrados como indeterminado como o2 faz não define essas propriedades.
Chamada interna "Função não vinculada" indireta através da functionName.call e functionName.apply :
Quando uma "Função não vinculada" é chamada por meio de functionName.call ou functionName.apply , o "objeto atual" (e, portanto, o valor de "this" ) é definido como o valor do parâmetro "this" (primeiro parâmetro) passado para chamar / aplicar . O código a seguir demonstra o mesmo.
O código acima mostra claramente que o valor "this" para qualquer "Função NÃO Limitada" pode ser alterado através de chamada / aplicação . Além disso, se o parâmetro "this" não for explicitamente passado para chamar / aplicar , "objeto atual" (e, portanto, o valor de "this") será definido como "window" no modo Non strict e "undefined" no modo strict.
Dentro da chamada "Função vinculada" (ou seja, uma função que foi vinculada ao chamar functionName.bind ):
Uma função vinculada é uma função cujo valor "this" foi corrigido. O código a seguir demonstrou como "isso" funciona em caso de função vinculada
Conforme indicado no código acima, "este" valor para qualquer "Função vinculada" NÃO PODE ser alterado através de chamada / aplicação . Além disso, se o parâmetro "this" não for explicitamente passado para ligação, o "objeto atual" (e, portanto, o valor de "this" ) será definido como "window" no modo Non strict e "undefined" no modo strict. Mais uma coisa. A ligação de uma função já vinculada não altera o valor "this" . Ele permanece definido como o valor definido pela primeira função de ligação.
Durante a criação de objetos por meio de "novo" :
Dentro de uma função construtora, o "objeto atual" (e, portanto, o valor de "this" ) faz referência ao objeto que está sendo criado no momento por meio de "novo", independentemente do status de ligação da função. No entanto, se o construtor for uma função vinculada, ele será chamado com um conjunto predefinido de argumentos, conforme definido para a função vinculada.
Manipulador de eventos DOM interno do Inline :
Veja o seguinte snippet HTML
O "this" nos exemplos acima se refere ao elemento "button" e ao elemento "div", respectivamente.
No primeiro exemplo, a cor da fonte do botão deve ser definida em branco quando ele é clicado.
No segundo exemplo, quando o elemento "div" é clicado, ele deve chamar a função OnDivClick com seu segundo parâmetro referenciando o elemento div clicado. No entanto, o valor "this" no OnDivClick NÃO DEVE referenciar o elemento div clicado . Ele deve ser definido como o "objeto de janela" ou "indefinido" nos modos Não restrito e Rigoroso, respectivamente (se OnDivClick for uma função não acoplada ) ou definido como um valor Limite predefinido (se OnDivClick for uma função vinculada )
A seguir, resume o artigo inteiro
No contexto global "isso" sempre se refere ao objeto "janela"
Sempre que uma função é invocada, ela é invocada no contexto de um objeto ( "objeto atual" ). Se o objeto atual não for fornecido explicitamente, o objeto atual é o "objeto de janela" no modo NÃO estrito e "indefinido" no modo estrito por padrão.
O valor "this" dentro de uma função Non Bound é a referência ao objeto no contexto em que a função é invocada ( "objeto atual" )
O valor "this" em uma função Non Bound pode ser substituído por chamada e aplicar métodos da função.
O valor "this" é fixo para uma função Limitada e não pode ser substituído por chamar e aplicar métodos da função.
A função de ligação e já vinculada não altera o valor "this". Ele permanece definido como o valor definido pela primeira função de ligação.
O valor "this" dentro de um construtor é o objeto que está sendo criado e inicializado
O valor "this" em um manipulador de eventos DOM embutido é referência ao elemento para o qual o manipulador de eventos é fornecido.
fonte
Provavelmente, o artigo mais detalhado e abrangente sobre
this
é o seguinte:Explicação suave da palavra-chave 'this' em JavaScript
A idéia subjacente
this
é entender que os tipos de chamada de função têm uma importância significativa na configuração dethis
valor.Ao ter problemas para identificar
this
, não se pergunte:mas não pergunte a si mesmo:
Para uma função de seta (caso especial de transparência de contexto), pergunte-se:
Essa mentalidade é correta ao lidar com
this
e evita dores de cabeça.fonte
this
palavra - chave?Esta é a melhor explicação que eu já vi: Entenda JavaScripts isso com o Clarity
Existem quatro cenários em que isso pode ser confuso:
Ele fornece exemplos de código, explicações e soluções, que achei muito úteis.
fonte
Em termos pseudoclássicos, o modo como muitas palestras ensinam a palavra-chave 'this' é como um objeto instanciado por um construtor de classe ou objeto. Cada vez que um novo objeto é construído a partir de uma classe, imagine que, sob o capô, uma instância local de um objeto 'this' seja criada e retornada. Lembro que ensinou assim:
fonte
this
é um dos conceitos incompreendidos no JavaScript porque se comporta de maneira um pouco diferente de um lugar para outro. Simplesmente,this
refere-se ao "proprietário" da função que estamos executando atualmente .this
ajuda a obter o objeto atual (também conhecido como contexto de execução) com o qual trabalhamos. Se você entender em qual objeto a função atual está sendo executada, poderá entender facilmente qualthis
é a corrente.Acima, criamos 3 variáveis com o mesmo nome 'val'. Um no contexto global, um dentro de obj e o outro dentro de InnerMethod of obj. O JavaScript resolve identificadores dentro de um contexto específico, subindo a cadeia de escopo de local para global.
Poucos lugares onde
this
podem ser diferenciadosChamando um método de um objeto
Quando a linha1 é executada, o JavaScript estabelece um contexto de execução (EC) para a chamada de função, configurando
this
o objeto referenciado pelo que veio antes do último "." . Então, na última linha, você pode entender quea()
foi executado no contexto global, que é owindow
.With Constructor
this
pode ser usado para se referir ao objeto que está sendo criadoQuando new
Person()
é executado, um objeto completamente novo é criado.Person
é chamado ethis
está definido para referenciar esse novo objeto.Chamada de função
Se faltarmos a
new
palavra-chave,whatIsThis
refere-se ao contexto mais global que ela pode encontrar (window
)Com manipuladores de eventos
Se o manipulador de eventos estiver embutido,
this
refere-se ao objeto globalAo adicionar o manipulador de eventos por meio do JavaScript,
this
refere-se ao elemento DOM que gerou o evento..apply()
.call()
e.bind()
var that = this
significa em JavaScriptfonte
O valor "this" depende do "contexto" no qual a função é executada. O contexto pode ser qualquer objeto ou o objeto global, ou seja, janela.
Portanto, a semântica "disso" é diferente das linguagens tradicionais de POO. E isso causa problemas: 1. quando uma função é passada para outra variável (provavelmente, um retorno de chamada); e 2. quando um fechamento é invocado a partir de um método membro de uma classe.
Nos dois casos, isso é definido como janela.
fonte
Whould esta ajuda? (A maior parte da confusão de 'this' no javascript é proveniente do fato de que geralmente não está vinculado ao seu objeto, mas do escopo de execução atual - isso pode não ser exatamente como ele funciona, mas sempre é assim para mim - veja o artigo para uma explicação completa)
fonte
Um pouco de informação sobre esta palavra - chave
Vamos registrar a
this
palavra-chave no console no escopo global sem mais código, masNo cliente / navegador, a
this
palavra-chave é um objeto global que éwindow
e
Em Server / Node / Javascript, a
this
palavra-chave de tempo de execução também é um objeto global que émodule.exports
Lembre-se
exports
é apenas uma referência amodule.exports
fonte
este uso para o escopo assim
o valor de txt1 e txt é o mesmo no exemplo acima $ (this) = $ ('# tbleName tbody tr') é o mesmo
fonte
Eu tenho uma opinião diferente
this
das outras respostas que espero que sejam úteis.Uma maneira de observar o JavaScript é ver que há apenas uma maneira de chamar uma função 1 . Isto é
Sempre há algum valor fornecido
objectForThis
.Tudo o resto é açúcar sintático para
functionObject.call
Portanto, tudo o mais pode ser descrito pela forma como ele se traduz
functionObject.call
.Se você acabou de chamar uma função, então
this
é o "objeto global" que no navegador é a janelaEm outras palavras,
foi efetivamente traduzido para
Observe que, se você usar o modo estrito,
this
seráundefined
que significa
Em outras palavras,
foi efetivamente traduzido para
Em JavaScript, existem operadores como
+
e-
e*
. Há também o operador de ponto que é.
o
.
operador, quando usado com uma função à direita e um objeto à esquerda, significa efetivamente "passar o objeto quantothis
à função".Exemplo
Em outras palavras
bar.foo()
traduz emconst temp = bar.foo; temp.call(bar);
Observe que não importa como a função foi criada (principalmente ...). Tudo isso produzirá os mesmos resultados
Novamente, todos esses são apenas açúcar sintático para
Uma outra ruga é a cadeia de protótipos. Quando você usa
a.b
JavaScript primeiros olhares sobre o objeto referenciado diretamente pora
para a propriedadeb
. Seb
não for encontrado no objeto, o JavaScript procurará no protótipo do objeto para encontrarb
.Existem várias maneiras de definir o protótipo de um objeto, o mais comum em 2019 é a
class
palavra - chave. Para os propósitos dethis
embora isso não importe. O que importa é que, ao procurar no objetoa
por propriedade,b
se encontrar propriedadeb
no objeto ou em sua cadeia de protótipos, seb
acabar sendo uma função, as mesmas regras acima se aplicam. Asb
referências de função serão chamadas usando ocall
método e passandoa
como objectForThis, como mostrado no topo desta resposta.Agora. Vamos imaginar que criamos uma função que define explicitamente
this
antes de chamar outra função e depois a chamamos com o.
operador (ponto)Após a tradução para usar
call
,obj.bar()
torna-seconst temp = obj.bar; temp.call(obj);
. Quando entramos nabar
função que chamamos,foo
mas passamos explicitamente outro objeto para objectForThis; assim, quando chegamos ao foo,this
esse objeto interno.Isto é o que ambos
bind
e=>
funções efetivamente fazer. Eles são mais açúcar sintático. Eles efetivamente constroem uma nova função invisível exatamente comobar
acima, quethis
é definida explicitamente antes de chamar qualquer função especificada. No caso de bind,this
é definido como o que você passabind
.Observe que, se
functionObject.bind
não existisse, poderíamos fazer nossos próprios assime então poderíamos chamar assim
Funções de seta, o
=>
operador é açúcar sintático para ligaçãoé o mesmo que
Assim como
bind
, uma nova função invisível é criada que chama a função fornecida com um valor vinculado,objectForThis
mas, ao contráriobind
do objeto a ser vinculado, está implícita. É o quethis
acontece quando o=>
operador é usado.Então, assim como as regras acima
obj.foo()
traduz paraconst temp = obj.foo; temp.call(obj);
que meios o operador de seta dentrofoo
se ligaráobj
a uma nova função invisível e retornará a nova função invisível à qual está atribuídab
.b()
funcionará como sempre,b.call(window)
oub.call(undefined)
chama a nova função invisívelfoo
criada. Essa função invisível ignora othis
passado para ele e passaobj
como objectForThis` para a função de seta.O código acima se traduz em
1
apply
é outra função semelhante acall
Mas a partir do ES6 conceitualmente, você pode até traduzir isso para
fonte
Resumo
this
Javascript:this
é determinado pela forma como a função não é chamada, onde foi criada!this
é determinado pelo objeto que resta do ponto. (window
no espaço global)this
refere-se ao elemento DOM no qual o evento foi chamado.new
palavra-chave, o valor dethis
refere-se ao objeto recém-criadothis
com as funções:call
,apply
,bind
Exemplo:
Exemplo de ouvintes de eventos:
Construtor de exemplo:
fonte
Para entender "isso" corretamente, é preciso entender o contexto, o escopo e a diferença entre eles.
Escopo : no escopo javascript está relacionado à visibilidade das variáveis, o escopo é obtido com o uso da função. (Leia mais sobre o escopo)
Contexto : o contexto está relacionado aos objetos. Refere-se ao objeto ao qual uma função pertence. Quando você usa a palavra-chave “this” do JavaScript, ela se refere ao objeto ao qual a função pertence. Por exemplo, dentro de uma função, quando você diz: "this.accoutNumber", você está se referindo à propriedade "accoutNumber", que pertence ao objeto ao qual essa função pertence.
Se o objeto "myObj" possui um método chamado "getMyName", quando a palavra-chave JavaScript "this" é usada dentro de "getMyName", refere-se a "myObj". Se a função "getMyName" foi executada no escopo global, "this" se refere ao objeto de janela (exceto no modo estrito).
Agora vamos ver um exemplo:
Executar um código acima na saída do navegador:
De acordo com a saída que você está dentro do contexto do objeto de janela, também é visível que o protótipo de janela se refere ao objeto.
Agora vamos tentar dentro de uma função:
Resultado:
A saída é a mesma porque registramos a variável 'this' no escopo global e no escopo funcional, não alteramos o contexto. Nos dois casos, o contexto era o mesmo, relacionado ao objeto viúvo .
Agora vamos criar nosso próprio objeto. Em javascript, você pode criar um objeto de várias maneiras.
Resultado:
Portanto, a partir do exemplo acima, descobrimos que a palavra-chave 'this' se refere a um novo contexto relacionado ao myObj, e o myObject também possui uma cadeia de protótipos para Object.
Vamos dar outro exemplo:
saída: faz sentido, certo? (leia comentários)
Se você tiver problemas para entender o exemplo acima, tente com nosso próprio retorno de chamada;
resultado:
Agora vamos entender o escopo, o Self, o IIFE e ISTO como se comporta
Saída é bastante impressionante, certo?
fonte
Resposta simples:
A palavra-chave "this" depende sempre do contexto da chamada. Eles são mencionados abaixo.
A FUNÇÃO É CHAMADA COM NOVA PALAVRA-CHAVE
Se a função for chamada com a palavra-chave NEW, ESTA será vinculada ao objeto recém-criado.
Acima, isso será vinculado ao objeto 'myCar'
A FUNÇÃO É CHAMADA EXPLICITAMENTE USANDO MÉTODOS DE CHAMADA E APLICAÇÃO.
Nesse caso, ESTE será vinculado ao objeto que é explicitamente passado para a função.
SE A FUNÇÃO É CHAMADA COM OBJETO IMPLICITAMENTE, ENTÃO ESTE SERÁ LIMITADO AO OBJETO
QUANDO A FUNÇÃO É CHAMADA SEM QUALQUER CONTEXTO, ENTÃO ISSO SERÁ LIMITADO A OBJETO GLOBAL
NO MODO ESTRITO, ESTE NÃO SERÁ DEFINIDO
fonte