Почему это работает в Node.js
консоли (протестировано в 4.1.1 и 5.3.0), но не работает в браузере (протестировано в Chrome)? Этот блок кода должен создавать и вызывать анонимную функцию, которая ведет журнал Ok
.
() => {
console.log('Ok');
}()
Кроме того, хотя вышеперечисленное работает в Node, это не работает:
n => {
console.log('Ok');
}()
Ни это:
(n) => {
console.log('Ok');
}()
Странно то, что при добавлении параметра он на самом деле бросает SyntaxError
в немедленно вызываемую часть.
(n => { console.log("Ok"); })();
работает?(n => { console.log("Ok"); })()
работает даже в консоли Chrome DevNode.js
первая версия больше не работает.Ответы:
Вам нужно сделать это выражение функции вместо определения функции, которое не требует имени и делает его допустимым JavaScript.
Является эквивалентом IIFE
И возможная причина, по которой это работает в Node.js, но не в chrome, заключается в том, что его синтаксический анализатор интерпретирует его как функцию, выполняемую самостоятельно, так как
Node.js
Это нормально работает в выражениях функций и Chrome и Firefox, и большинство браузеров интерпретирует это так. Вы должны вызвать его вручную.Наиболее распространенный способ сказать парсеру, что он должен ожидать выражение функции, - это просто заключить его в скобки, потому что в JavaScript они не могут содержать операторов. В этот момент, когда синтаксический анализатор встречает ключевое слово function, он знает, что нужно проанализировать его как выражение функции, а не как объявление функции.
Что касается параметризованной версии , это будет работать.
источник
Node.js
и фактически записывает значение. Мой вопрос: почему это работает? А почему нет, когда я добавляю параметр?IIFE
s и знаю, как исправить мой код. Мне было просто любопытно, почему, например, мойIIFE
не работает приn
добавлении параметра, даже если он работал без параметра.function(){}()
в функциях стрелок? Если я хочу, чтобы объект функции выставлял выражения функций от этого.Ничто из этого не должно работать без скобок.
Зачем?
Потому что согласно спецификации:
Таким образом, ArrowFunction не может быть на LHS CallExpression .
То , что это фактически означает , в том , как
=>
следует интерпретировать, что он работает на такой же уровень , как операторы присваивания=
, и+=
т.д.Смыслx => {foo}()
не становится(x => {foo})()
x => ({foo}())
Таким образом, интерпретатор решает, что(
должно быть неправильно и выдает SyntaxErrorСуществовал ошибка на Бабеля об этом здесь тоже.
источник
() => ({console.log('Ok')}())
она больше не работает. Так что на самом деле это не так.console.log(...)
не является допустимым именем ключа.SyntaxError: Unexpected token (
(указывая на(
in()
в конце, а не(
inconsole.log(...)
).(
причина, по которой переводчик сдался после изнурительных попыток найти правильную интерпретацию и уходит «тогда это должно быть неправильно»), что может быть ошибочным в любом случае, потому что я не знаю, как на самом деле написан переводчикПричина, по которой вы сталкиваетесь с подобными проблемами, заключается в том, что консоль сама пытается эмулировать глобальную область действия контекста, на который вы в настоящий момент ориентируетесь. Он также пытается получить возвращаемые значения из операторов и выражений, которые вы пишете в консоли, чтобы они отображались как результаты. Взять, к примеру:
Здесь он выполняется так, как если бы это было выражение, но вы написали его так, как если бы это было утверждение. В обычных сценариях значение будет отброшено, но здесь код должен быть внутренне искажен (например, обернут весь оператор в контекст функции и
return
оператор), что вызывает всевозможные странные эффекты, включая проблемы, с которыми вы сталкиваетесь.Это также одна из причин того, что некоторые чистые коды ES6 в скриптах работают нормально, но не в консоли Chrome Dev Tools.
Попробуйте выполнить это в консоли Node и Chrome:
В Node или
<script>
теге он работает просто отлично, но в консоли он даетUncaught SyntaxError: Unexpected identifier
. Он также дает вам ссылку на источник, в формеVMxxx:1
которого вы можете щелкнуть, чтобы проверить оцениваемый источник, который отображается как:Так почему он это сделал?
Ответ заключается в том, что он должен преобразовать ваш код в выражение, чтобы результат мог быть возвращен вызывающей стороне и отображен в консоли. Вы можете сделать это, заключив оператор в круглые скобки, что делает его выражением, но также делает синтаксически некорректным приведенный выше блок (выражение не может иметь объявление блока).
Консоль пытается исправить эти крайние случаи, будучи умным в отношении кода, но это выходит за рамки этого ответа, я думаю. Вы можете отправить сообщение об ошибке, чтобы узнать, исправят ли они это.
Вот хороший пример чего-то очень похожего:
https://stackoverflow.com/a/28431346/46588
Самый безопасный способ заставить ваш код работать, это убедиться, что он может быть запущен как выражение, и проверить
SyntaxError
исходную ссылку, чтобы увидеть, каков фактический код выполнения, и пересмотреть решение из этого. Обычно это пара стратегически расположенных скобок.Вкратце: консоль пытается максимально точно имитировать глобальный контекст выполнения, но из-за ограничений взаимодействия с движком v8 и семантики JavaScript это иногда трудно или невозможно решить.
источник
Я задал вопрос, как это:
и это ответ Кайла Симпсона:
против
- getify (@getify) 12 июня 2020 г.
источник
console.log(x)(4)
.