Chamada de function indireta em JavaScript

Existem coisas como

f.call(...) f.apply(...) 

Mas então há esta

 (1, alert)('Zomg what is this????!!!11') 

“1” não parece significar muito neste contexto, o seguinte funciona muito bem:

 (null, alert)('Zomg what is this????!!!11') (1, null, alert)('Zomg what is this????!!!11') (undefined, alert)('Zomg what is this????!!!11') 

Você poderia apontar para uma parte específica do ECMAScript que descreve essa syntax?

Você está apenas usando o Comma Operator .

Esse operador avalia apenas seus operandos da esquerda para a direita e retorna o valor do segundo, por exemplo:

 (0, 1); // 1 ('foo', 'bar'); // 'bar' 

No contexto de chamar uma function, a avaliação do operando simplesmente obterá um valor, não uma referência, isso faz com que this valor dentro da function invocada aponte para o object global (ou será undefined no novo ECMAScript 5 Strict Modo).

Por exemplo:

 var foo = 'global.foo'; var obj = { foo: 'obj.foo', method: function () { return this.foo; } }; obj.method(); // "obj.foo" (1, obj.method)(); // "global.foo" 

Como você pode ver, a primeira chamada, que é uma chamada direta, this valor dentro do method se referirá corretamente a obj (retornando "obj.foo" ), a segunda chamada, a avaliação feita pelo operador de vírgula fará o this valor para apontar para o object global (produzindo "global.foo" ).

Esse padrão tem se tornado bastante popular atualmente, para fazer chamadas indiretas para eval , isso pode ser útil no ES5 strict mode, para obter uma referência ao object global, por exemplo (imagine que você está em um ambiente sem navegador, window não está disponível):

 (function () { "use strict"; var global = (function () { return this || (1,eval)("this"); })(); })(); 

No código acima, a function anônima interna será executada dentro de uma unidade de código de modo estrito, que resultará em ter this valor como undefined .

O || O operador agora pegará o segundo operando, a chamada eval , que é uma chamada indireta, e avaliará o código no ambiente léxico e variável global.

Mas, pessoalmente, neste caso, sob o modo estrito, prefiro usar o construtor Function para obter o object global:

 (function () { "use strict"; var global = Function('return this')(); })(); 

As funções que são criadas com o construtor da Function são estritas apenas se começarem com uma diretiva de uso restrito, elas não “herdam” o rigor do contexto atual como declaração de function ou expressões de function.

É o operador de vírgula , que avalia seus dois operandos e retorna o valor do segundo.

Então, algo como (null, alert) avalia a function de alert , que você pode chamar imediatamente usando parênteses.

Está descrito na seção 11.14 da ECMA-262 (PDF).

O operador vírgula faz com que as expressões sejam avaliadas sequencialmente. Embrulhar as expressões entre parênteses retorna o valor da última expressão. Então (1, alert)("hello") é funcionalmente equivalente a:

 1; alert("hello"); 

Fora do topo da minha cabeça, não consigo pensar em uma razão para fazer isso.

Intereting Posts