Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Скобки в Javascript (https://javascript.ru/forum/misc/83208-skobki-v-javascript.html)

voraa 15.10.2021 08:08

Скобки в Javascript
 
По идее Javascript никак не должен изменять и оптимизировать скобки.
Как написано, так и выполняется.

let x = a+(b+c);

будет и выполняться примерно как

let _;
_ = b+c;
x = a+_;


И никак иначе
Но.

'use strict'
const A = {
   f(x) {console.log (this, x)}
};

A.f (10);  // => {A}, 10

let t = A.f;

t(20) ;  // => undefined, 20

let _;
(_ = A.f) (30);   // => undefined, 30

(A.f) (40)  // => {A}, 40   Почему?


Разве последний случай не тоже самое, что

let _;
(_ = A.f) (40);


Ведь сначала должно выполнится действие в скобках, т.е "вычислить" A.f и потом вызвать этот результат, как функцию.

Aetae 15.10.2021 08:36

Нет. Скобки "что-то = что-то другое" это expression(вражение), т.е. у него есть результат.

Скобочки выполняют expression, результатом которого будет то, что лежит в "что-то" на конец операции.
Просто же "что-то" - это не выражение и работает как есть.

Alexandroppolus 15.10.2021 08:54

В последнем случае интерпретатор просто выкидывает скобки за ненадобностью. Считается, что они тут бесполезны и ничего не меняют.
Известный пример - вызов "глобального eval":
(0,eval)(str)

Здесь евал не имеет доступа к внутреннему скоупу. Без "0," вызывается обычный.

voraa 15.10.2021 09:05

И действительно.

(null, A.f) (40)  // => undefined, 40


Хотя странно. Ведь вычисления в любом случае производятся. f может быть суровым геттером, который вычислят бог знает что, а потом выдает результат

Alexandroppolus 15.10.2021 09:40

Да и даже без геттера, просто доступ через точку - тоже вычисление.
Тут можно "логически обосновать" оба варианта. Просто выбрали один из двух. Типа, что "скобки не поменяют порядок вычислений", и потому их можно сначала выкинуть, а потом уже разбирать код.

MallSerg 16.10.2021 00:07

Не стоит гадать и отгадывать.

JavaScript это формализованный язык программирования что означает что у него есть четкие правила (грамматики) с помощью которых выполняется синтаксический разбор. Все эти правила описаны в спецификации языка.

В первом случае «(_ = A.f) (30);» в части выражения «(_ = A.f)» есть оператор "=" который и превращает эту часть выражения в так называемый AssignmentExpression.
AssignmentExpression не может быть частью другого выражения.
Для выражения которое является частью другого выражения используют понятие MemberExpression (т.е. такое к которому можно добавить параметры и попробовать вызвать как функцию).
Кстати запятая в выражении то же делает выражение как AssignmentExpression https://262.ecma-international.org/8.0/#prod-Expression.

voraa 16.10.2021 15:37

На самом деле из синтаксиса ничего не следует
MemberExpression тут A.f
А (A.f) - это как раз AssignmentExpression. И знак = тут совершенно не при чем.
Но поведение объясняется в Runtime Semantics: Evaluation в примечании к п 12.2.10.4 https://262.ecma-international.org/8...ics-evaluation
Правда я не совсем понял при чем там typeof.

MallSerg 16.10.2021 19:30

Если у меня появляются такие вопросы я использую AST парсер.
Синтаксическое дерево хорошо показывает структуру кода так как ее понимает интерпретатор.

https://astexplorer.net/


Часовой пояс GMT +3, время: 02:39.