Подтвердить что ты не робот

Как работает оператор группировки JavaScript?

Как работает оператор группировки JavaScript?

1 + 2;
(1 + 2);

function(){ return 1} + "text";  // SyntaxError
(function(){return 1} + "text");

Учитывая приведенный выше код, у меня есть следующие вопросы:

  • Почему 1 + 2; работает без синтаксической ошибки, тогда как function(){ return 1} + "text" вызывает SyntaxError?
  • Как оператор группировки в (function(){return 1} + "text") исправляет ошибку синтаксиса?
4b9b3361

Ответ 1

Когда function находится в начале инструкции, он рассматривается как начало определения имени функции, которое должно выглядеть следующим образом:

function someName() { return 1; }

Это выражение, а не выражение, поэтому оно не может использоваться как часть более крупного выражения.

Фактически, это недействительно, чтобы иметь этот оператор без имени. Вы получаете синтаксическую ошибку:

function() { return 1}

сам по себе.

Но когда вы помещаете его после скобки, это уже не начало инструкции, поэтому это выражение функции, которое возвращает функцию как значение. Затем он может использоваться как суб-выражение в более крупном выражении.

Это не оператор группировки, который делает это, просто тот факт, что он не в начале инструкции. Например, вы также можете написать:

var foo = function() { return 1 } + "text";

Ответ 2

1+2; - это то, что работает на большинстве языков с синтаксисом C-inspired. Одним из видов разрешенных операторов в Javascript является оператор, который просто содержит выражение. Это позволяет операторам, которые содержат только вызов функции, например foo(); или присваивание, такие как x=5;. Да, присваивания в Javascript считаются выражениями вместо операторов, поэтому вам разрешено снимать себя в ногу и назначать задание в условном выражении if (классическая ошибка = vs ==). В конце концов, компилятору было бы сложно запретить бесполезные выражения-выражения, такие как 1+2;, сохраняя при этом foo() и x = 5;.

Объект function(){} vs (function(){}) - это привидение Javascript. Javascript имеет разные правила в грамматике для "операторов объявления функций" и "выражений функций" . В первом примере функция анализируется как оператор, который нельзя добавить к другим вещам. Во втором случае в скобках функция анализируется как выражение, которое позволяет добавлять ее к другим вещам.

Вот почему "self invoking function pattern" всегда добавляет пару скобок в анонимную функцию.

(function(){
     ...
 }())

Ответ 3

Вопрос о операторе группировки() или операторе приоритета.

Предварительное примечание: скобки, используемые в функции [name]() {} ", являются частью синтаксиса функции (idem для функции invokation), а не оператора группировки.

Оператор группировки имеет наивысший приоритет над любым другим оператором, именно потому, что его роль заключается в изменении приоритета содержащегося в нем выражения (т.е. в скобках). Это означает, что выражение в круглых скобках полностью оценивается до того, как его значение будет использовано в остальной части выражения. В дальнейшем:

(1+2); // strictly equivalent to 1+2;
       // because nothing more in the expression

или

var x = ("3"==3)? "ok":"ko"; // grouping operator is useless as well

... но (как указано в Barmar'answer): синтаксис "function() {return 1;}", когда put(), управляется оператором группировки, и рассматривается как выражение, которое должно быть выполнено до использования в полном заявлении, и есть 2 последствия:

  • разрешена анонимная функция, поскольку мы находимся в выражении функции;
  • выражение функции должно иметь аргументы, предоставляемые его параметрам, и если вы ожидаете возвращаемого значения (note2) - вторая пара скобок является обязательной, чтобы содержать аргументы или аргументы без аргументов. (function() {return 1;}());

Примечание2: в исходном вопросе упоминался пример:

(function(){return 1} + "text");  //-> function(){return 1}text

как не возвращающий синтаксическую ошибку: он правильный, но возвращает код функции как строковое значение, а не значение 1, за которым следует строка "текст". Зачем? потому что для выполнения не были предусмотрены скобки. Мы должны написать:

(function(){return 1}()) + "text"; //-> 1text