Pourquoi cela fonctionne-t-il dans une Node.js
console (testé en 4.1.1 et 5.3.0) mais ne fonctionne pas dans le navigateur (testé dans Chrome)? Ce bloc de code doit créer et appeler une fonction anonyme qui enregistre Ok
.
() => {
console.log('Ok');
}()
De plus, bien que ce qui précède fonctionne dans Node, cela ne fonctionne pas:
n => {
console.log('Ok');
}()
Ni ceci:
(n) => {
console.log('Ok');
}()
Ce qui est étrange, c'est que lorsque le paramètre est ajouté, il lance en fait un SyntaxError
à la partie qui appelle immédiatement.
(n => { console.log("Ok"); })();
marche?(n => { console.log("Ok"); })()
fonctionne même dans la console de développement ChromeNode.js
la première version ne fonctionne plus.Réponses:
Vous devez en faire une expression de fonction au lieu d' une définition de fonction qui n'a pas besoin d'un nom et en fait un JavaScript valide.
Est l'équivalent de IIFE
Et la raison possible pour laquelle cela fonctionne dans Node.js mais pas dans chrome est parce que son analyseur l'interprète comme une fonction auto-exécutable, comme ceci
fonctionne très bien dans
Node.js
Ceci est une expression de fonction et Chrome et Firefox et la plupart des navigateurs l'interprètent de cette façon. Vous devez l'invoquer manuellement.La façon la plus largement acceptée de dire à l'analyseur d'attendre une expression de fonction est simplement de l'encapsuler dans des parens, car en JavaScript, les parens ne peuvent pas contenir d'instructions. À ce stade, lorsque l'analyseur rencontre le mot-clé de fonction, il sait l'analyser comme une expression de fonction et non comme une déclaration de fonction.
Concernant la version paramétrée , cela fonctionnera.
la source
Node.js
et enregistre réellement la valeur. Ma question est pourquoi ça marche? Et pourquoi ce n'est pas le cas lorsque j'ajoute le paramètre?IIFE
s et je sais comment corriger mon code. J'étais juste curieux de savoir pourquoi, par exemple, monIIFE
ne fonctionne pas lorsque len
paramètre est ajouté, même si cela fonctionnait sans le paramètre.function(){}()
fonctions fléchées? Si je veux que les expressions de fonction exposées de l'objet fonction se protègent contre cela.Aucun de ceux-ci ne devrait fonctionner sans parenthèses.
Pourquoi?
Parce que selon les spécifications:
Ainsi, une ArrowFunction ne peut pas être sur la LHS d'une CallExpression .
Ce que cela signifie effectivement dans la façon dont
=>
doit être interprété, c'est que cela fonctionne sur le même type de niveau que les opérateurs d'affectation=
,+=
etc.Sensx => {foo}()
ne devient pas(x => {foo})()
x => ({foo}())
Ainsi l'interpréteur décide que le(
doit avoir été faux et lance une SyntaxErrorIl y avait un bug sur Babel à ce sujet ici aussi.
la source
() => ({console.log('Ok')}())
cela ne fonctionne plus. Donc, il ne l'interprète pas vraiment de cette façon.console.log(...)
n'est pas un nom de clé valide.SyntaxError: Unexpected token (
(pointant vers(
le()
à la fin, pas vers l'(
entréeconsole.log(...)
).(
que l'interprète a abandonné après des tentatives épuisantes pour trouver une interprétation valide et "ça doit être faux alors"), ce qui peut être faux de toute façon parce que je ne sais pas comment l'interprète est vraiment écritLa raison pour laquelle vous rencontrez des problèmes comme celui-ci est que la console elle-même essaie d'émuler la portée globale du contexte que vous ciblez actuellement. Il essaie également de capturer les valeurs de retour des instructions et des expressions que vous écrivez dans la console, afin que les résultats apparaissent. Prenons par exemple:
Ici, il s'exécute comme s'il s'agissait d'une expression, mais vous l'avez écrit comme s'il s'agissait d'une instruction. Dans les scripts normaux, la valeur serait ignorée, mais ici, le code doit être mutilé en interne (comme envelopper l'instruction entière avec un contexte de fonction et une
return
instruction), ce qui provoque toutes sortes d'effets étranges, y compris les problèmes que vous rencontrez.C'est également l'une des raisons pour lesquelles certains codes ES6 nus dans les scripts fonctionnent correctement, mais pas dans la console Chrome Dev Tools.
Essayez de l'exécuter dans la console Node et Chrome:
Dans Node ou une
<script>
balise ça marche très bien, mais dans la console, ça donneUncaught SyntaxError: Unexpected identifier
. Il vous donne également un lien vers la source sous la formeVMxxx:1
duquel vous pouvez cliquer pour inspecter la source évaluée, qui apparaît comme:Alors pourquoi a-t-il fait ça?
La réponse est qu'il doit convertir votre code en une expression afin que le résultat puisse être renvoyé à l'appelant et affiché dans la console. Vous pouvez le faire en entourant l'instruction entre parenthèses, ce qui en fait une expression, mais cela rend également le bloc ci-dessus syntaxiquement incorrect (une expression ne peut pas avoir de déclaration de bloc).
La console essaie de résoudre ces cas extrêmes en étant intelligente sur le code, mais cela dépasse le cadre de cette réponse, je pense. Vous pouvez déposer un bogue pour voir si c'est quelque chose qu'ils envisageraient de corriger.
Voici un bon exemple de quelque chose de très similaire:
https://stackoverflow.com/a/28431346/46588
Le moyen le plus sûr de faire fonctionner votre code est de vous assurer qu'il peut être exécuté en tant qu'expression et d'inspecter le
SyntaxError
lien source pour voir quel est le code d'exécution réel et de procéder à l' ingénierie inverse d'une solution à partir de cela. Habituellement, cela signifie une paire de parenthèses stratégiquement placées.En bref: la console essaie d'émuler le contexte d'exécution global aussi précisément que possible, mais en raison des limitations d'interaction avec le moteur v8 et la sémantique JavaScript, cela est parfois difficile voire impossible à résoudre.
la source
J'ai posé une question comme celle-ci:
et voici la réponse de Kyle Simpson:
contre
- getify (@getify) 12 juin 2020
la source
console.log(x)(4)
.