¿Por qué funciona esto en una Node.js
consola (probado en 4.1.1 y 5.3.0) pero no funciona en el navegador (probado en Chrome)? Este bloque de código debe crear e invocar una función anónima que registre Ok
.
() => {
console.log('Ok');
}()
Además, aunque lo anterior funciona en Node, esto no funciona:
n => {
console.log('Ok');
}()
Ni esto:
(n) => {
console.log('Ok');
}()
Lo extraño es que cuando se agrega el parámetro, en realidad arroja un SyntaxError
en la parte que invoca de inmediato.
(n => { console.log("Ok"); })();
funciona?(n => { console.log("Ok"); })()
funciona incluso en la consola de desarrollo de ChromeNode.js
la primera versión ya no funciona.Respuestas:
Debe convertirlo en una expresión de función en lugar de una definición de función que no necesita un nombre y lo convierte en un JavaScript válido.
Es el equivalente de IIFE
Y la posible razón por la que esto funciona en Node.js pero no en Chrome es porque su analizador lo interpreta como una función de ejecución automática, ya que esto
funciona bien en
Node.js
Esta es una expresión de función y Chrome y Firefox y la mayoría del navegador lo interpreta de esta manera. Necesita invocarlo manualmente.La forma más ampliamente aceptada de decirle al analizador que espere una expresión de función es simplemente envolverla en parens, porque en JavaScript, los parens no pueden contener declaraciones. En este punto, cuando el analizador encuentra la palabra clave de función, sabe analizarla como una expresión de función y no como una declaración de función.
En cuanto a la versión parametrizada , esto funcionará.
fuente
Node.js
y realmente registra el valor. Mi pregunta es ¿por qué funciona? ¿Y por qué no cuando agrego el parámetro?IIFE
sy sé cómo arreglar mi código. Tenía curiosidad por qué, por ejemplo, miIIFE
no funciona cuandon
se agrega el parámetro, a pesar de que funcionó sin el parámetro.function(){}()
las funciones de flecha? Si quiero el objeto de función, las expresiones de función expuestas protegen contra eso.Ninguno de estos debería funcionar sin paréntesis.
¿Por qué?
Porque de acuerdo con la especificación:
Por lo tanto, una función de flecha no puede estar en el LHS de una expresión de llamada .
Lo que esto significa efectivamente en cómo
=>
debe interpretarse es que funciona en el mismo tipo de nivel que los operadores de asignación=
,+=
etc.Sentidox => {foo}()
no se convierte(x => {foo})()
x => ({foo}())
Entonces el intérprete decide que(
debe haber estado equivocado y lanza un SyntaxErrorHubo un error en la Babel de ello aquí , también.
fuente
() => ({console.log('Ok')}())
ya no funciona. Entonces, en realidad no lo interpreta de esa manera.console.log(...)
no es un nombre de clave válido.SyntaxError: Unexpected token (
(señalando el(
en el()
en el extremo, no el(
deconsole.log(...)
).(
hizo que el intérprete se rindiera después de agotar los intentos de encontrar una interpretación válida y se va "esto debe estar mal entonces"), lo cual puede estar mal de todos modos porque no sé cómo está realmente escrito el intérpreteLa razón por la que ve problemas como este es porque la consola en sí misma trata de emular el alcance global del contexto al que se dirige actualmente. También intenta capturar los valores de retorno de las declaraciones y expresiones que escribe en la consola, para que aparezcan como resultados. Tomemos, por ejemplo:
Aquí, se ejecuta como si fuera una expresión, pero la ha escrito como si fuera una declaración. En los scripts normales, el valor se descartaría, pero aquí, el código debe ser mutilado internamente (como envolver toda la declaración con un contexto de función y una
return
declaración), lo que causa todo tipo de efectos extraños, incluidos los problemas que está experimentando.Esta es también una de las razones por las cuales algunos códigos básicos de ES6 en scripts funcionan bien pero no en la consola de Chrome Dev Tools.
Intente ejecutar esto en Node y la consola de Chrome:
En Node o una
<script>
etiqueta funciona bien, pero en la consola, daUncaught SyntaxError: Unexpected identifier
. También le proporciona un enlace a la fuente en laVMxxx:1
que puede hacer clic para inspeccionar la fuente evaluada, que se muestra como:Entonces, ¿por qué hizo esto?
La respuesta es que necesita convertir su código en una expresión para que el resultado pueda ser devuelto a la persona que llama y se muestre en la consola. Puede hacer esto envolviendo la declaración entre paréntesis, lo que la convierte en una expresión, pero también hace que el bloque anterior sea sintácticamente incorrecto (una expresión no puede tener una declaración de bloque).
La consola intenta solucionar estos casos extremos al ser inteligente con el código, pero eso está más allá del alcance de esta respuesta, creo. Puede presentar un error para ver si eso es algo que considerarían solucionar.
Aquí hay un buen ejemplo de algo muy similar:
https://stackoverflow.com/a/28431346/46588
La forma más segura de hacer que su código funcione es asegurarse de que se pueda ejecutar como una expresión e inspeccionar el
SyntaxError
enlace de origen para ver cuál es el código de ejecución real y aplicarle una solución de ingeniería inversa. Por lo general, significa un par de paréntesis estratégicamente ubicados.En resumen: la consola intenta emular el contexto de ejecución global con la mayor precisión posible, pero debido a las limitaciones de la interacción con el motor v8 y la semántica de JavaScript, esto a veces es difícil o imposible de resolver.
fuente
Hice una pregunta como esta:
y esta es la respuesta de Kyle Simpson:
vs
- getify (@getify) 12 de junio de 2020
fuente
console.log(x)(4)
.