Почему самоисполняемый аноним работает?

Я знаю о самоисполняющемся анонимном. И обычно мы создаем их как

(function(){ return 1;})()

причина - функция парсера, которая не запускалась, если мы используем

function(){ return 1}()

Но сегодня я обнаружил, что следующий код тоже работает (проверьте порядок скобок)

(function(){ return 1;}())

function(){ return 1; }() все равно выдает мне SyntaxError, как и положено

Пожалуйста, объясните, почему? Спасибо за ссылку, чтобы получить более подробную информацию

P.S. вопрос про (function(){ return 1;}()) вариант!


person Vasiliy Vanchuk    schedule 16.05.2016    source источник
comment
вы не закрыли скобки в ( function(){ return 1; }()   -  person Lun Zhang    schedule 16.05.2016
comment
это текст, который содержит функцию -- там все правильно   -  person Vasiliy Vanchuk    schedule 16.05.2016
comment
Потому что это неправильный синтаксис. Это: function(){ return 1; }() просто не определяется как допустимый синтаксис.   -  person XCS    schedule 16.05.2016
comment
@LunZhang Ты имеешь в виду в последней строке? Первая скобка не является частью кода.   -  person Sebastian Simon    schedule 16.05.2016
comment
@Cristy Вопросы в том, почему это РАБОТАЕТ, а не «почему НЕ работает».   -  person Vasiliy Vanchuk    schedule 16.05.2016
comment
@VasiliyVanchuk Прочитайте это: en.wikipedia.org/wiki/Immediately-invoked_function_expression   -  person XCS    schedule 16.05.2016
comment
@Cristy «стиль Дугласа Крокфорда» не знала. Спасибо   -  person Vasiliy Vanchuk    schedule 16.05.2016
comment
По той же причине {a: 1, b: 2}[a] не работает. Здесь {} — это блок, а не объект. Это потому, что { интерпретируется как оператор, а не как выражение. ({a: 1, b: 2})[a] или ({a: 1, b: 2}[a]) работают, потому что () заставляет интерпретировать {} как выражение (объект). То же самое и с функциями, потому что есть функциональные операторы и функциональные выражения. Почему? Потому что именно так был разработан JavaScript.   -  person Sebastian Simon    schedule 16.05.2016
comment
Если вы поймете, почему работает первое, то поймете, почему работает и второе. Второе должно быть не более загадочным, чем первое.   -  person    schedule 16.05.2016
comment
... и этот ответ на другой вопрос дает довольно подробное объяснение того, почему либо работает, а последний не работает .   -  person    schedule 16.05.2016


Ответы (2)


(function() {})()

и

(function() {}())

эквивалентны.

Чтобы вызвать второй пример, вы можете включить оператор + перед функцией

+function(){ return 1 }()

См. раздел выражение немедленно вызываемой функции (IIFE).

person guest271314    schedule 16.05.2016
comment
Есть операторы получше, чем +. Причина в том, что + перегружен как бинарный оператор, поэтому, если вы случайно забудете точку с запятой после предыдущего выражения, он попытается добавить это предыдущее выражение в функцию. По сути, это та же проблема, что и при использовании (). Если вы собираетесь использовать альтернативный оператор для принудительного выражения, используйте унарный оператор, например !. - person ; 16.05.2016
comment
@squint Есть операторы получше, чем + , Если вы собираетесь использовать альтернативный оператор для принудительного выражения, используйте унарный оператор, например !. Да, но не для этого конкретного случая; !function(){ return 1 }() возвращает false вместо 1 - person guest271314; 17.05.2016
comment
@squint В качестве альтернативы, ;null, function(){ return 1 }(); - person guest271314; 17.05.2016
comment
Если возвращаемое значение захватывается, никакой оператор не должен превращать функцию в допустимое выражение. Но да, лучше все, чтобы избежать неожиданной оценки оператора. Я использовал void время от времени в прошлом. - person ; 17.05.2016

Фраза IIFE является лучшим термином для этих функций. Выражения немедленно вызываемой функции.

Что касается того, почему они одинаковы: внешние скобки () просто составляют выражение, а () вместе выполняют вызов.

(function(){ return 1;})()
is the same as:
(function(){ return 1;}())


(function(){ return 1;})()
becomes
(functionexpression)()
becomes
functionexpression()

и

(function(){ return 1;}())
becomes
(functionExpression())
becomes   
functionExpression()

по той же причине, что

(3)+2 совпадает с ((3)+2).

ИЗМЕНИТЬ

function(){ return 1; }()

НЕ работает, потому что function statement отличается от function expression. Функциональные операторы не могут быть вызваны немедленно.

person Jeremy J Starcher    schedule 16.05.2016