ES6 немедленно вызвал функцию стрелки
Почему это работает в консоли Node.js
(протестировано в 4.1.1 и 5.3.0), но не работает в браузере (проверено в Chrome)? Этот блок кода должен создавать и вызывать анонимную функцию, которая регистрирует Ok
.
() => {
console.log('Ok');
}()
Кроме того, хотя выше работает в Node, это не работает:
n => {
console.log('Ok');
}()
И это:
(n) => {
console.log('Ok');
}()
Нечетным является то, что при добавлении параметра он фактически выдает SyntaxError
в вызывающей немедленно части.
Ответы
Ответ 1
Вам нужно сделать это выражением функции вместо определения функции, которая не нуждается в имени и делает его действительным JavaScript.
(() => {
console.log('Ok');
})()
Является эквивалентом IIFE
(function(){
console.log('Ok')
})();
И возможная причина, по которой это работает в Node.js, но не в хроме, состоит в том, что его синтаксический анализатор интерпретирует его как функцию самоисполнения, поскольку этот
function() { console.log('hello'); }();
отлично работает в Node.js
Это выражение функции, chrome и firefox, и большинство браузеров интерпретирует его таким образом. Вам нужно вызвать его вручную.
Самый распространенный способ сказать парсеру ожидать выражения функции - просто обернуть его в parens, потому что в JavaScript парс не может содержать операторов. В этот момент, когда синтаксический анализатор встречает ключевое слово function, он разбирается в нем как выражение функции, а не объявление функции.
Что касается параметризованной версии, это будет работать.
((n) => {
console.log('Ok');
})()
Ответ 2
Ни одно из них не должно работать без круглых скобок.
Почему?
Потому что согласно спецификации:
Таким образом, функция ArrowFunction не может находиться в LHS вызывного вызова.
То, что это эффективно означает, как следует интерпретировать =>
, заключается в том, что он работает на том же уровне, что и операторы присваивания =
, +=
и т.д.
Значение
-
x => {foo}()
не становится (x => {foo})()
- Интерпретатор пытается интерпретировать его как
x => ({foo}())
- Таким образом, это все еще SyntaxError
- Таким образом, интерпретатор решает, что
(
, должно быть, был неправильным и выбрасывает SyntaxError
Здесь была проблема с Babel об этом здесь.
Ответ 3
Причина, по которой вы видите такие проблемы, заключается в том, что сама консоль пытается эмулировать глобальную область контекста, на который вы сейчас нацеливаете. Он также пытается захватить возвращаемые значения из операторов и выражений, которые вы пишете на консоли, чтобы они отображались как результаты. Возьмем, например:
> 3 + 2
< 5
Здесь он выполняется так, как если бы это было выражение, но вы написали его, как будто это было утверждение. В обычных сценариях значение будет отбрасываться, но здесь код должен быть внутренне искажен (например, обертывание всего оператора контекстом функции и инструкцией return
), которая вызывает всевозможные странные эффекты, в том числе проблемы, re experience.
Это также одна из причин, почему некоторый открытый код ES6 в скриптах работает нормально, но не в консоли Chrome Dev Tools.
Попробуйте выполнить это в Node и консоли Chrome:
{ let a = 3 }
В теге Node или <script>
он работает нормально, но в консоли он дает Uncaught SyntaxError: Unexpected identifier
. Он также дает вам ссылку на источник в форме VMxxx:1
, которую вы можете щелкнуть, чтобы проверить оцениваемый источник, который отображается как:
({ let a = 3 })
Так зачем это делал?
Ответ заключается в том, что он должен преобразовать ваш код в выражение, чтобы результат можно было вернуть вызывающему и отобразить в консоли. Вы можете сделать это, завернув оператор в круглые скобки, что делает его выражением, но также делает блок выше синтаксически неправильным (выражение не может иметь объявление блока).
Консоль пытается исправить эти случаи краев, будучи умными в отношении кода, но это выходит за рамки этого ответа, я думаю. Вы можете указать ошибку, чтобы убедиться, что это будет исправлено.
Вот хороший пример чего-то очень похожего:
fooobar.com/info/61745/...
Самый безопасный способ заставить ваш код работать, чтобы убедиться, что он может быть запущен как выражение и проверить исходную ссылку SyntaxError
, чтобы узнать, что представляет собой фактический код выполнения, и реконструировать решение из этого. Обычно это означает пару стратегически расположенных круглых скобок.
Вкратце: консоль пытается как можно точнее эмулировать глобальный контекст выполнения, но из-за ограничений взаимодействия с движком v8 и семантикой JavaScript это иногда трудно или невозможно решить.