Por que isso funciona em um Node.js
console (testado em 4.1.1 e 5.3.0) mas não funciona no navegador (testado no Chrome)? Esse bloco de código deve criar e chamar uma função anônima que faça logon Ok
.
() => {
console.log('Ok');
}()
Além disso, enquanto o acima funciona no Node, isso não funciona:
n => {
console.log('Ok');
}()
Nem isso:
(n) => {
console.log('Ok');
}()
O que é estranho é que, quando o parâmetro é adicionado, ele realmente lança um SyntaxError
na parte que chama imediatamente.
(n => { console.log("Ok"); })();
funciona?(n => { console.log("Ok"); })()
funciona mesmo no console do desenvolvedor do ChromeNode.js
primeira versão não está mais funcionando.Respostas:
Você precisa transformá-la em uma expressão de função em vez de na definição de função, que não precisa de um nome e o torna um JavaScript válido.
É o equivalente a IIFE
E a possível razão pela qual isso funciona no Node.js, mas não no chrome, é porque seu analisador o interpreta como uma função de execução automática, pois
funciona bem em
Node.js
Esta é uma expressão de função e chrome e firefox e a maior parte do navegador interpreta dessa maneira. Você precisa invocá-lo manualmente.A maneira mais aceita de dizer ao analisador que espere uma expressão de função é envolvê-la em parênteses, porque no JavaScript, parênteses não podem conter instruções. Nesse ponto, quando o analisador encontra a palavra-chave function, ele sabe analisá-la como uma expressão de função e não como uma declaração de função.
Em relação à versão parametrizada , isso funcionará.
fonte
Node.js
e efetivamente registra o valor. Minha pergunta é por que isso funciona? E por que não acontece quando adiciono o parâmetro?IIFE
s e sei como corrigir meu código. Fiquei curioso por que, por exemplo, meuIIFE
não funciona quando on
parâmetro é adicionado, mesmo que funcionasse sem o parâmetro.function(){}()
nas funções de seta? Se eu quiser que o objeto de função exposto, as expressões de função se protejam contra isso.Nada disso deve funcionar sem parênteses.
Por quê?
Porque de acordo com as especificações:
Portanto, uma ArrowFunction não pode estar no LHS de uma CallExpression .
O que isso significa efetivamente em como
=>
deve ser interpretado é que ele funciona no mesmo tipo de nível que os operadores de atribuição=
,+=
etc.Significadox => {foo}()
não se torna(x => {foo})()
x => ({foo}())
Portanto, o intérprete decide que(
deve estar errado e lança um SyntaxErrorTambém houve um bug em Babel aqui .
fonte
() => ({console.log('Ok')}())
não funciona mais. Portanto, ele realmente não interpreta dessa maneira.console.log(...)
não é um nome de chave válido.SyntaxError: Unexpected token (
(apontando para o(
no()
final e não o(
internoconsole.log(...)
).(
fez o intérprete desistir após tentativas exaustivas de encontrar uma interpretação válida e continuar "este deve ser errado, então"), que pode ser de qualquer maneira errada, porque eu não sei como o intérprete é realmente escritaA razão pela qual você está enfrentando problemas como esse é que o próprio console tenta emular o escopo global do contexto que você está direcionando atualmente. Ele também tenta capturar valores de retorno de instruções e expressões que você escreve no console, para que apareçam como resultados. Tomemos, por exemplo:
Aqui, ele é executado como se fosse uma expressão, mas você a escreveu como se fosse uma declaração. Em scripts normais, o valor seria descartado, mas aqui, o código deve ser mutilado internamente (como agrupar toda a instrução com um contexto de função e uma
return
instrução), o que causa todos os tipos de efeitos estranhos, incluindo os problemas que você está enfrentando.Esse também é um dos motivos pelos quais alguns códigos ES6 vazios nos scripts funcionam bem, mas não no console das Ferramentas de Desenvolvimento do Chrome.
Tente executar isso no console do Node e do Chrome:
No Node ou em uma
<script>
tag, ele funciona muito bem, mas no console, ele forneceUncaught SyntaxError: Unexpected identifier
. Também fornece um link para a fonte no formato noVMxxx:1
qual você pode clicar para inspecionar a fonte avaliada, que aparece como:Então, por que fez isso?
A resposta é que ele precisa converter seu código em uma expressão para que o resultado possa ser retornado ao chamador e exibido no console. Você pode fazer isso colocando a instrução entre parênteses, o que a torna uma expressão, mas também torna o bloco acima sintaticamente incorreto (uma expressão não pode ter uma declaração de bloco).
O console tenta corrigir esses casos extremos, sendo esperto quanto ao código, mas acho que está além do escopo desta resposta. Você pode registrar um bug para ver se isso é algo que eles considerariam consertar.
Aqui está um bom exemplo de algo muito semelhante:
https://stackoverflow.com/a/28431346/46588
A maneira mais segura de fazer seu código funcionar é garantir que ele possa ser executado como uma expressão e inspecionar o
SyntaxError
link de origem para ver qual é o código de execução real e fazer a engenharia reversa de uma solução a partir disso. Geralmente significa um par de parênteses estrategicamente posicionados.Resumindo: o console tenta emular o contexto de execução global com a maior precisão possível, mas devido às limitações de interação com o mecanismo v8 e a semântica do JavaScript, isso às vezes é difícil ou impossível de resolver.
fonte
Eu fiz uma pergunta como esta:
e esta é a resposta de Kyle Simpson:
vs
- getify (@getify) 12 de junho de 2020
fonte
console.log(x)(4)
.