Tenho uma pergunta sobre como o ponteiro "this" é tratado em um cenário de função aninhada.
Digamos que eu insira este código de exemplo a seguir em uma página da web. Recebo um erro quando chamo a função aninhada "doSomeEffects ()". Verifiquei no Firebug e ele indica que, quando estou naquela função aninhada, o ponteiro "this" está na verdade apontando para o objeto "janela" global - o que eu não esperava. Não devo estar entendendo algo corretamente porque pensei que, como declarei a função aninhada dentro de uma função do objeto, ela deveria ter um escopo "local" em relação à função (ou seja, o ponteiro "this" estaria se referindo ao próprio objeto como como é na minha primeira declaração "if").
Quaisquer sugestões (sem trocadilhos) seriam apreciadas.
var std_obj = {
options : { rows: 0, cols: 0 },
activeEffect : "none",
displayMe : function() {
// the 'this' pointer is referring to the std_obj
if (this.activeEffect=="fade") { }
var doSomeEffects = function() {
// the 'this' pointer is referring to the window obj, why?
if (this.activeEffect=="fade") { }
}
doSomeEffects();
}
};
std_obj.displayMe();
fonte
this
refere-se ao objeto no qual a função é chamada.var self = this;
e, em seguida, referir-se àself
função interna por meio de fechamento.doSomeEffects
não está associado a nenhum obj em particular, por issothis
é considerada a janela, a mãe de todos os elementos.Respostas:
Em JavaScript, o
this
objeto é realmente baseado em como você faz suas chamadas de função.Em geral, existem três maneiras de configurar o
this
objeto:someThing.someFunction(arg1, arg2, argN)
someFunction.call(someThing, arg1, arg2, argN)
someFunction.apply(someThing, [arg1, arg2, argN])
Em todos os exemplos acima, o
this
objeto serásomeThing
. Chamar uma função sem um objeto pai principal geralmente obterá o objeto global que, na maioria dos navegadores, significa owindow
objeto.fonte
this.doSomeEffects();
base na sua resposta, mas ainda não funciona. Por quê?this
emthis.doSomeEffects()
pontos parastd_obj
. Conforme explicado na resposta acima, se uma função não tiver referência de objeto, elathis
será considerada um objeto de janela.Uma vez que esta parece ser uma das questões mais votadas desse tipo, deixe-me adicionar, após todos esses anos, a solução ES6 usando funções de seta:
fonte
this
não faz parte do escopo de fechamento, pode ser considerado um parâmetro adicional para a função que está vinculada ao local da chamada. Se o método não for chamado como um método, o objeto global será passado comothis
. No navegador, o objeto global é idêntico awindow
. Por exemplo, considere a seguinte função,e o seguinte objeto,
Se você chamar a função usando a sintaxe do método, como,
então
this
está ligado aobj
.Se você chamar someFunction () diretamente, como,
então
this
está ligado ao objeto global, isto éwindow
.A solução mais comum é capturar isso no fechamento, como,
fonte
Há uma diferença entre variáveis de fechamento e "this". "this" é realmente definido pelo invocador da função, enquanto as variáveis explícitas permanecem intactas dentro do bloco de declaração de função conhecido como anexo. Veja o exemplo abaixo:
você pode experimentar aqui: http://jsfiddle.net/kSTBy/
O que está acontecendo em sua função é "doSomeEffects ()", está sendo chamado explicitamente, isso significa contexto ou o "this" da função é a janela. se "doSomeEffects" fosse um método de protótipo, por exemplo, this.doSomeEffects em dizer "myObject", então myObject.doSomeEffects () faria com que "this" fosse "myObject".
fonte
_this.name = myFirstObject this.name = mySecondObject
Para entender esta questão, tente obter a saída para o seguinte snippet
O código acima irá gerar o seguinte no console:
Na função externa, tanto this quanto self se referem a myObject e, portanto, podem referenciar e acessar foo corretamente.
Na função interna, porém, isso não se refere mais a meuObjeto. Como resultado, this.foo é indefinido na função interna, enquanto a referência à variável local self permanece no escopo e é acessível lá. (Antes do ECMA 5, isso na função interna se referia ao objeto de janela global; ao passo que, a partir do ECMA 5, isso na função interna seria indefinido.)
fonte
this
refere-se ao objeto janela (em um ambiente de navegador) ou objeto GLOBAL (em um ambiente node.js)this
não se refere mais a janelaConforme explicado por Kyle, você pode usar
call
ouapply
para especificarthis
dentro da função:Este é o conceito aplicado ao seu código:
JsFiddle
fonte
Também recebi um aviso " Acesso de referência potencialmente inválido a um campo de classe por meio disso "
fonte
Como não foi mencionado, mencionarei que usar
.bind()
é uma solução -Aqui está um exemplo mais simples -
É verdade que usar uma função de seta
=>
parece mais simples e fácil para o programador. No entanto, deve-se ter em mente que um escopo léxico provavelmente exigirá mais trabalho em termos de processamento e memória para configurar e manter esse escopo léxico, em comparação com simplesmente associar uma função athis
um ponteiro via.bind()
.Parte do benefício de desenvolver classes em JS era fornecer um método para fazer
this
mais confiável o presente e disponível, para desviar da programação funcional e escopos lexicais e, assim, reduzir a sobrecarga.De MDN
fonte