Pregunta ¿Qué hace el signo de exclamación antes de la función?


!function () {}();

1020
2017-09-20 21:21


origen


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 función declaración. Necesitarías una invocación, foo(), para ejecutar realmente la función.

Ahora, cuando agreguemos el signo de exclamación aparentemente inocuo: !function foo() {} lo convierte en un expresión. Ahora es un expresión de función.

los ! solo no invoca la función, por supuesto, pero ahora podemos poner () al final: !function foo() {}() que tiene mayor prioridad que ! y llama instantáneamente a la función.

Entonces, lo que el autor está haciendo es guardar un byte por expresión de función; una forma más legible de escribirlo sería esta:

(function(){})();

Finalmente, ! hace que la expresión sea verdadera. Esto es porque por defecto todo el retorno IIFE undefinedque nos deja con !undefined cual es true. No particularmente útil.


1737
2018-04-13 20:02



La función:

function () {}

no devuelve nada (o indefinido).

A veces queremos llamar a una función correcta a medida que la creamos. Es posible que tengas la tentación de probar esto:

function () {}()

pero resulta en una SyntaxError.

Utilizando el ! operador antes de que la función haga que se trate como una expresión, por lo que podemos llamarlo:

!function () {}()

Esto también devolverá el valor booleano opuesto al 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 () {})()

327
2017-09-20 21:28



Hay un buen punto para usar ! para invocación de función marcada en guía de JavaScript de airbnb

Idea general para usar esta técnica en archivos separados (también conocidos como módulos) que luego se concatenan. Es importante advertir que los archivos se supone que están concatenados por herramientas que colocan un nuevo archivo en una nueva línea (que de todos modos es un comportamiento común para la mayoría de las herramientas de concat). En ese caso usando ! ayudará a evitar el error en caso de que el módulo concatenado previamente pierda el punto y coma al final, y sin embargo eso le dará flexibilidad para ponerlos en cualquier orden sin preocupaciones.

!function abc(){}()
!function bca(){}();

Funcionará igual que

!function abc(){}()
;(function bca(){})();

pero ahorra dos personajes y se ve mejor arbitrariamente.

Y, por cierto, cualquiera de +,-,~,void los operadores tienen el mismo efecto, en términos de invocación de la función, con seguridad si tiene algo que utilizar para regresar de esa función, 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 un archivo de separación de código de un módulo y usa la herramienta concat para optimización (que hace una línea de un trabajo de archivo), entonces la construcción

!function abc(/*no returns*/) {}()
+function bca() {/*no returns*/}()

Hará una ejecución segura del código, igual que una primera muestra de código.

Este lanzará 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 se usen en el primer módulo. Entonces no son tan seguros si no tienes 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*/}()

46
2017-10-01 18:10



Devuelve si la instrucció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 tu 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. P.ej. el siguiente código no es válido porque se interpreta como una declaración de función que falta la requerida identificador (o nombre de la función)

function () { return false; }();  // syntax error

26
2017-09-20 21:25



Y aquí hay algo más que descubrí de la consola. Como se mencionó anteriormente, el signo de exclamación hace que la función devuelva un valor booleano.

Para el último de la sintaxis:

( function my_function() {} )()

Podemos hacer algo como:

(function add_them(a,b) { return a+b;} )(9,4)

Como una definición de función simultánea y llamada.

Editar:
Ahora me preguntaría ¿de qué sirve '!' tipo definición de función. Consideremos lo siguiente:

!function a_would_be_function() { alert("Do some junk but inside a function"); }()

querrías ejecutar una función como la de arriba, pero sin un '!' generaría un error Espero que esté claro.


5
2018-05-06 14:49



! es un lógico NO operador, es un operador booleano que invertirá algo en su opuesto.

Aunque puede omitir los paréntesis de la función invocada utilizando el EXPLOSIÓN (!) antes de la función, aún invertirá el retorno, que podría no ser lo que usted quería. Como en el caso de un IEFE, devolvería indefinido, que cuando se invierte se convierte en booleano verdadero.

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

3
2017-07-31 16:36



Es otra forma de escribir IIFE (expresión de función invocada inmediatamente).

Su otra forma de escribir -

(function( args ) {})()

igual que

!function ( args ) {}();

2
2018-03-06 09:56



Es solo para guardar un byte de datos cuando hacemos una minificación de JavaScript.

considere la siguiente función anónima

function (){}

Para hacer que lo anterior sea una función de invocación automática, generalmente cambiaremos el código anterior como

(function (){}())

Ahora agregamos dos caracteres adicionales (,) aparte de agregar () al final de la función 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 (,) acabamos de usar un personaje !


2
2017-09-05 10:05



! negará (opuesto) lo que sea que esperas como resultado, es decir, si tienes

var boy = true;
undefined
boy
true
!boy
false

cuando usted llama boy, tu resultado será true, pero en el momento en que agrega el ! cuando llamas boy, es decir !boy, tu resultado será false. Lo que en otras palabras quieres decir NotBoy, pero esta vez es básicamente un resultado booleano, true o false.

Eso es lo mismo que le sucede a la !function () {}(); expresión, corriendo solo function () {}(); le señalará un error, pero agregue ! justo en frente de tu function () {}(); expresión, lo hace todo lo contrario de la function () {}(); que debería devolverte true. El ejemplo se puede ver a continuación:

function () {}();
SyntaxError: function statement requires a name
!function () {}();
true

1
2018-01-13 15:55