!function () {}();
!function () {}();
Respuestas:
Sintaxis de JavaScript 101. Aquí hay una declaración de función :
function foo() {}
Tenga en cuenta que no hay punto y coma: esto es solo una declaración de función . Necesitaría una invocación,, foo()
para ejecutar realmente la función.
Ahora, cuando agregamos el signo de exclamación aparentemente inocuo: !function foo() {}
lo convierte en una expresión . Ahora es una expresión de función .
El !
solo no invoca la función, por supuesto, pero ahora podemos poner ()
al final: !function foo() {}()
que tiene mayor precedencia que !
e instantáneamente llama a la función.
Entonces, lo que está haciendo el autor es guardar un byte por expresión de función; una forma más legible de escribir sería esta:
(function(){})();
Por último, !
hace que la expresión vuelva verdadera. Esto se debe a que, por defecto, todos los IIFE devuelven undefined
, lo que nos deja con lo !undefined
que es true
. No particularmente útil.
!
devuelve boolean, todos lo sabemos, pero el gran punto que destaca es que también convierte la declaración de declaración de función en una expresión de función para que la función se pueda invocar inmediatamente sin ponerla entre paréntesis. No es obvio, y claramente la intención del codificador.
var foo =
rompe la ambigüedad de la declaración / expresión y simplemente puede escribir, var foo = function(bar){}("baz");
etc.
La función:
function () {}
no devuelve nada (o indefinido).
A veces queremos llamar a una función correctamente a medida que la creamos. Puede sentirse tentado a intentar esto:
function () {}()
pero resulta en a SyntaxError
.
El uso del !
operador antes de la función hace que se trate como una expresión, por lo que podemos llamarlo:
!function () {}()
Esto también devolverá el opuesto booleano del valor de retorno de la función, en este caso true
, porque !undefined
es true
. Si desea que el valor de retorno real sea el resultado de la llamada, intente hacerlo de esta manera:
(function () {})()
!
es convertir la declaración de función en una expresión de función, eso es todo.
!function
sintaxis
Hay un buen punto para usar la !
invocación de funciones marcada en la guía JavaScript de airbnb
Generalmente es una idea para usar esta técnica en archivos separados (también conocidos como módulos) que luego se concatenan. La advertencia aquí es que los archivos deben ser concatenados por herramientas que colocan el nuevo archivo en la nueva línea (que de todos modos es un comportamiento común para la mayoría de las herramientas de concat). En ese caso, el uso !
ayudará a evitar errores si el módulo concatenado anteriormente omitió el punto y coma final y, sin embargo, eso le dará la flexibilidad para colocarlos en cualquier orden sin preocupaciones.
!function abc(){}();
!function bca(){}();
Funcionará igual que
!function abc(){}();
(function bca(){})();
pero guarda un personaje y arbitrario se ve mejor.
Y, por cierto cualquiera de +
, -
, ~
, void
los operadores tienen el mismo efecto, en cuanto a la invocación de la función, a ciencia cierta si tiene que usar algo para volver de esa función que actuarían de manera 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?
pero si usa patrones IIFE para una separación de código de módulo de un archivo y usa la herramienta concat para la optimización (que hace que una línea sea un trabajo de archivo), entonces construcción
!function abc(/*no returns*/) {}()
+function bca() {/*no returns*/}()
Hará una ejecución de código segura, igual que una primera muestra de código.
Este arrojará un error porque JavaScript ASI no podrá hacer su trabajo.
!function abc(/*no returns*/) {}()
(function bca() {/*no returns*/})()
Una nota con respecto a los operadores unarios, harían un trabajo similar, pero solo en caso de que no lo usaran en el primer módulo. Por lo tanto, no son tan seguros si no tiene control total sobre la orden de concatenación.
Esto funciona:
!function abc(/*no returns*/) {}()
^function bca() {/*no returns*/}()
Esto no:
^function abc(/*no returns*/) {}()
!function bca() {/*no returns*/}()
Devuelve si la declaración puede evaluar a falso. p.ej:
!false // true
!true // false
!isValid() // is not valid
Puede usarlo dos veces para forzar un valor a booleano:
!!1 // true
!!0 // false
Entonces, para responder más directamente a su pregunta:
var myVar = !function(){ return false; }(); // myVar contains true
Editar: tiene el efecto secundario de cambiar la declaración de función a una expresión de función. Por ejemplo, el siguiente código no es válido porque se interpreta como una declaración de función a la que le falta el identificador requerido (o el nombre de la función ):
function () { return false; }(); // syntax error
var myVar = !function(){ return false; }()
podría omitir el me !
gusta var myVar = function(){ return false; }()
y la función se ejecutará correctamente y el valor de retorno no se verá afectado.
true
con !0
y false
con !1
. Ahorra 2 o 3 caracteres.
Es solo para guardar un byte de datos cuando hacemos la minificación de javascript.
considere la siguiente función anónima
function (){}
Para hacer lo anterior como función de auto invocación, generalmente cambiaremos el código anterior como
(function (){}())
Ahora agregamos dos caracteres adicionales (,)
además de agregar ()
al final de la función lo que es necesario para llamar a la función. En el proceso de minificación generalmente nos enfocamos en reducir el tamaño del archivo. Entonces también podemos escribir la función anterior como
!function (){}()
Aún así, ambas son funciones de invocación automática y también guardamos un byte. En lugar de 2 caracteres (,)
, solo usamos un personaje!
! es un operador NOT lógico , es un operador booleano que invertirá algo en su opuesto.
Aunque puede omitir los paréntesis de la función invocada utilizando BANG (!) Antes de la función, todavía invertirá el retorno, que podría no ser lo que deseaba. Como en el caso de un IEFE, volvería indefinido , que cuando se invierte se convierte en el verdadero booleano.
En su lugar, use el paréntesis de cierre y el BANG ( ! ) Si es necesario.
// 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
Otros operadores que trabajan ...
+(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
El signo de exclamación hace que cualquier función siempre devuelva un valor booleano.
El valor final es la negación del valor devuelto por la función.
!function bool() { return false; }() // true
!function bool() { return true; }() // false
Omitir !
en los ejemplos anteriores sería un SyntaxError .
function bool() { return true; }() // SyntaxError
Sin embargo, una mejor manera de lograr esto sería:
(function bool() { return true; })() // true
!
cambia la forma en que el tiempo de ejecución analiza la función. Hace que el tiempo de ejecución trate la función como una expresión de función (y no una declaración). Hace esto para permitir que el desarrollador invoque inmediatamente la función utilizando la ()
sintaxis. !
también se aplicará (es decir, negación) al resultado de invocar la expresión de función.
Es otra forma de escribir IIFE (expresión de función invocada inmediatamente).
Su otra forma de escribir:
(function( args ) {})()
igual que
!function ( args ) {}();
(function (args) {...})()
sintaxis más explícita y dejar ese !function
formulario a las herramientas de minificación y ofuscación.
!
negará (opuesto) lo que sea que esté esperando como resultado, es decir, si tiene
var boy = true;
undefined
boy
true
!boy
false
cuando llame boy
, su resultado será true
, pero en el momento en que agregue el !
al llamar boy
, es decir !boy
, su resultado será false
. En otras palabras, te refieres a NotBoy , pero esta vez es básicamente un resultado booleano, ya sea true
o false
.
Eso es lo mismo que le sucede a la !function () {}();
expresión, la ejecución solo le function () {}();
indicará un error, pero si se agrega !
justo delante de su function () {}();
expresión, es lo opuesto a lo function () {}();
que debería devolverle true
. El ejemplo se puede ver a continuación:
function () {}();
SyntaxError: function statement requires a name
!function () {}();
true