!function () {}();
!function () {}();
Respostas:
Sintaxe JavaScript 101. Aqui está uma declaração de função :
function foo() {}
Observe que não há ponto e vírgula: esta é apenas uma declaração de função . Você precisaria de uma chamada,, foo()
para realmente executar a função.
Agora, quando adicionamos o ponto de exclamação aparentemente inócuo: !function foo() {}
ele o transforma em uma expressão . Agora é uma expressão de função .
O !
sozinho não invoca a função, é claro, mas agora podemos colocar ()
no final: !function foo() {}()
que tem maior precedência do que !
e chama instantaneamente a função.
Então, o que o autor está fazendo é salvar um byte por expressão de função; uma maneira mais legível de escrever seria o seguinte:
(function(){})();
Por fim, !
faz com que a expressão retorne verdadeira. Isso ocorre porque, por padrão, todo retorno IIFE undefined
, o que nos deixa com o !undefined
que é true
. Não é particularmente útil.
!
retorna booleano, todos nós sabemos disso, mas o grande ponto a ser destacado é que ela também converte a declaração de declaração de função em uma expressão de função, para que a função possa ser chamada imediatamente sem colocá-la entre parênteses. Não é óbvio e claramente a intenção do codificador.
var foo =
breaks a declaração / expressão ambigüidade e você pode simplesmente escrever var foo = function(bar){}("baz");
etc.
A função:
function () {}
não retorna nada (ou indefinido).
Às vezes, queremos chamar uma função da maneira que a criamos. Você pode ficar tentado a tentar o seguinte:
function () {}()
mas resulta em a SyntaxError
.
Usar o !
operador antes da função faz com que ela seja tratada como uma expressão, para que possamos chamá-la:
!function () {}()
Isso também retornará o oposto booleano do valor de retorno da função, neste caso true
, porque !undefined
é true
. Se você deseja que o valor de retorno real seja o resultado da chamada, tente fazer o seguinte:
(function () {})()
!
é transformar a declaração de função em uma expressão de função, só isso.
!function
sintaxe
Há um bom ponto para usar !
a chamada de função marcada no guia JavaScript do airbnb
Geralmente, a idéia de usar esta técnica em arquivos separados (também conhecidos como módulos) é concatenada posteriormente. A ressalva aqui é que os arquivos devem ser concatenados por ferramentas que colocam o novo arquivo na nova linha (que é um comportamento comum para a maioria das ferramentas concat). Nesse caso, o uso !
ajudará a evitar erros no módulo se anteriormente concatenado perder o ponto e vírgula à direita, e ainda assim oferecerá a flexibilidade de colocá-los em qualquer ordem sem preocupações.
!function abc(){}();
!function bca(){}();
Funcionará da mesma forma que
!function abc(){}();
(function bca(){})();
mas salva um caractere e parece arbitrário melhor.
E pelo jeito qualquer um +
, -
, ~
, void
os operadores têm o mesmo efeito, em termos de invocar a função, com certeza se você tem que usar algo para retornar de que a função agiriam de forma diferente.
abcval = !function abc(){return true;}() // abcval equals false
bcaval = +function bca(){return true;}() // bcaval equals 1
zyxval = -function zyx(){return true;}() // zyxval equals -1
xyzval = ~function xyz(){return true;}() // your guess?
mas se você estiver usando padrões IIFE para uma separação de código de um arquivo e um módulo e usando a ferramenta concat para otimização (que faz um arquivo de uma linha e um trabalho), construção
!function abc(/*no returns*/) {}()
+function bca() {/*no returns*/}()
Realizará a execução segura do código, o mesmo que um primeiro exemplo de código.
Este erro gerará porque o JavaScript ASI não poderá executar seu trabalho.
!function abc(/*no returns*/) {}()
(function bca() {/*no returns*/})()
Uma observação sobre operadores unários, eles fariam um trabalho semelhante, mas apenas no caso, eles não usaram no primeiro módulo. Portanto, eles não são tão seguros se você não tiver controle total sobre a ordem de concatenação.
Isso funciona:
!function abc(/*no returns*/) {}()
^function bca() {/*no returns*/}()
Isso não:
^function abc(/*no returns*/) {}()
!function bca() {/*no returns*/}()
Retorna se a instrução pode ser avaliada como falsa. por exemplo:
!false // true
!true // false
!isValid() // is not valid
Você pode usá-lo duas vezes para coagir um valor a booleano:
!!1 // true
!!0 // false
Portanto, para responder mais diretamente à sua pergunta:
var myVar = !function(){ return false; }(); // myVar contains true
Editar: tem o efeito colateral de alterar a declaração da função para uma expressão de função. Por exemplo, o código a seguir não é válido porque é interpretado como uma declaração de função que está ausente do identificador necessário (ou nome da função ):
function () { return false; }(); // syntax error
var myVar = !function(){ return false; }()
pode omitir o !
mesmo var myVar = function(){ return false; }()
e a função será executada corretamente e o valor de retorno será intocado.
true
por !0
e false
com !1
. Ele salva 2 ou 3 caracteres.
É apenas para salvar um byte de dados quando fazemos minificação de javascript.
considere a função anônima abaixo
function (){}
Para fazer o que foi dito acima como função auto-invocável, geralmente alteraremos o código acima como
(function (){}())
Agora, adicionamos dois caracteres extras (,)
além da adição ()
no final da função, necessária para chamar a função. No processo de minificação, geralmente nos concentramos em reduzir o tamanho do arquivo. Então, também podemos escrever a função acima como
!function (){}()
Ainda assim, ambas são funções auto-invocáveis e também salvamos um byte. Em vez de 2 caracteres, (,)
usamos apenas um caractere!
! é um operador NÃO lógico , é um operador booleano que inverte algo para o seu oposto.
Embora você possa ignorar os parênteses da função chamada usando o BANG (!) Antes da função, ele ainda inverte o retorno, que pode não ser o que você queria. Como no caso de um IEFE, ele retornaria indefinido , que quando invertido se torna o verdadeiro booleano.
Em vez disso, use o parêntese de fechamento e o BANG ( ! ), Se necessário.
// I'm going to leave the closing () in all examples as invoking the function with just ! and () takes away from what's happening.
(function(){ return false; }());
=> false
!(function(){ return false; }());
=> true
!!(function(){ return false; }());
=> false
!!!(function(){ return false; }());
=> true
Outros operadores que trabalham ...
+(function(){ return false; }());
=> 0
-(function(){ return false; }());
=> -0
~(function(){ return false; }());
=> -1
Operadores combinados ...
+!(function(){ return false; }());
=> 1
-!(function(){ return false; }());
=> -1
!+(function(){ return false; }());
=> true
!-(function(){ return false; }());
=> true
~!(function(){ return false; }());
=> -2
~!!(function(){ return false; }());
=> -1
+~(function(){ return false; }());
+> -1
O ponto de exclamação faz com que qualquer função sempre retorne um valor booleano.
O valor final é a negação do valor retornado pela função.
!function bool() { return false; }() // true
!function bool() { return true; }() // false
Omitir !
nos exemplos acima seria um SyntaxError .
function bool() { return true; }() // SyntaxError
No entanto, uma maneira melhor de conseguir isso seria:
(function bool() { return true; })() // true
!
altera a maneira como o tempo de execução analisa a função. Faz com que o tempo de execução trate a função como uma expressão de função (e não uma declaração). Isso é feito para permitir que o desenvolvedor chame imediatamente a função usando a ()
sintaxe. !
também se aplicará (ou seja, negação) ao resultado da chamada da expressão da função.
É outra maneira de escrever IIFE (expressão de função chamada imediatamente).
Sua outra maneira de escrever -
(function( args ) {})()
igual a
!function ( args ) {}();
(function (args) {...})()
sintaxe mais explícita e deixaria esse !function
formulário nas ferramentas de minificação e ofuscação.
!
negará (oposto) o que você espera como resultado, ou seja, se você tiver
var boy = true;
undefined
boy
true
!boy
false
quando você ligar boy
, seu resultado será true
, mas no momento em que você adicionar o !
quando ligar boy
, ou seja !boy
, seu resultado será false
. O que, em outras palavras, você quer dizer NotBoy , mas desta vez é basicamente um resultado booleano, seja true
ou false
.
É a mesma coisa que acontece com a !function () {}();
expressão: executar apenas function () {}();
sinalizará um erro, mas será adicionado !
à frente da sua function () {}();
expressão, tornando o oposto do function () {}();
que deve retornar você true
. Exemplo pode ser visto abaixo:
function () {}();
SyntaxError: function statement requires a name
!function () {}();
true