Por que “this” em uma função anônima é indefinido ao usar estrito?


85

Por que isso está em uma função anônima indefinida ao usar javascript no modo estrito? Eu entendo por que isso pode fazer sentido, mas não consegui encontrar uma resposta concreta.

Exemplo:

(function () {
    "use strict";

    this.foo = "bar"; // *this* is undefined, why?
}());

Teste em um violino: http://jsfiddle.net/Pyr5g/1/ Verifique o logger (firebug).


4
Observe que isso não tem nada a ver com funções anônimas, mas com o método de invocação. Veja este violino modificado (veja o log do console).
Phrogz

@Phrogz: Pode ser daí que veio parte da confusão. Obrigado por apontar isso.
T. Junghans,

Respostas:


101

É porque, até ECMAscript 262 edição 5, havia uma grande confusão se as pessoas que estavam usando o constructor pattern, esqueciam de usar a newpalavra - chave. Se você esqueceu de usar newao chamar uma função de construtor no ES3, thisreferenciou o objeto global ( windowem um navegador) e você iria sobrecarregar o objeto global com variáveis.

Que era um comportamento terrível e para que as pessoas em ECMA decidiu, apenas para definir thisa undefined.

Exemplo:

function myConstructor() {
    this.a = 'foo';
    this.b = 'bar';
}

myInstance     = new myConstructor(); // all cool, all fine. a and b were created in a new local object
myBadInstance  = myConstructor(); // oh my gosh, we just created a, and b on the window object

A última linha lançaria um erro no ES5 estrito

"TypeError: this is undefined"

(que é um comportamento muito melhor)


4
Isso faz sentido. Você tem uma referência para fazer backup da declaração?
Rob W

1
@RobW: Eu mesmo teria que fazer uma busca, mas ouvi Douglas Crockford várias vezes em que ele disse que esse era o motivo dessa decisão.
jAndy

1
É mencionado em JavaScript: The Good Parts de Crockford. Ele é descrito em detalhes. Não sobre a decisão da ECMA, no entanto.
madr.

1
Esta é a razão lógica pela qual o modo estrito padroniza para indefinido. A outra razão lógica é a eficiência, a outra razão lógica é que this === windowé confuso e vaza o escopo global como um token em funções
Raynos

2
@jAndy: Obrigado pela resposta. Isso faz sentido. Eu também encontrei uma explicação compacta das alterações para este sobre javascriptweblog.wordpress.com/2011/05/03/... : "Mais notavelmente, se o primeiro argumento para chamar ou aplicar é nulo ou indefinido, a este valor da função chamada não será convertido para o objeto global. "
T. Junghans

15

Existe um mecanismo chamado "boxing" que envolve ou altera o thisobjeto antes de entrar no contexto da função chamada. No seu caso, o valor de thisdeveria ser undefinedporque você não está chamando a função como um método de um objeto. Se o modo não for estrito, neste caso, ele será substituído pelo windowobjeto. No strictmodo está sempre inalterado, é por isso que está undefinedaqui.

Você pode encontrar mais informações em
https://developer.mozilla.org/en/JavaScript/Strict_mode


@samuel então como podemos atribuir uma variável ao objeto janela no modo estrito ??
Null Pointer

8

De acordo com a resposta de This Stack Overflow , você pode usar thisfunções anônimas internas, simplesmente chamando .call(this)no final dela.

(function () {
    "use strict";

    this.foo = "bar";
}).call(this);

4
Observe que thisserá o Windowobjeto neste caso, o que pode não ser desejado
Ninjakannon

Esta resposta não explica a pergunta feita.
Anvesh Checka
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.