Объясните порядок вычисления

148
26 сентября 2019, 04:10

Вывожу в консоль такой код -сonsole.log(++g + fun(g));. В g число, а в fun return g + g. Как я понял выражение вызова функции имеет больший приоритет чем инкремент и сначала должно выполнится оно. Но g вычисляется уже увеличенной в fun(g), почему? Ведь инкрементирование должно быть после выражения вызова.

Answer 1

Если я правильно понимаю, нужно учитывать не только приоритет операторов, но и ассоциативность. Приоритет можно воспринимать как «где подразумеваются круглые скобки», а ассоциативность — в каком порядке происходит вычисление.

Высший приритет не означает, что его связка будет выполнена всегда первой, где бы он ни стоял, вне зависимости от ассоциативности операторов с низшим приоритетом. Он означает, что результат этой связки станет новым операндом до того, как дело дойдёт до оператора низшего приоритета.

В MDN русский перевод начала страницы о приоритете не такой полный, как английский текст, где добавлено уточнение: операторы с высшим приоритетом становятся операндами для операторов с низшим приоритетом.

Оператор сложения имеет ассоциативность слева направо. Поэтому левое значение будет всё равно вычислено раньше функции. Приоритет вызова функции означает только, когда именно будет добавлен вызов. Например, если бы приоритет вызова функции был ниже, чем у сложения, вычисление производилось бы так: ((++g) + fun)(g). А при настоящих правилах оно производится так: (++g) + (fun(g)).

Порядок, насколько я понимаю, такой.

При префиксном инкременте:

  1. g увеличивается.
  2. g становится операндом.
  3. fun(g) вызывается с увеличенным g.
  4. Результат вызова становится операндом.
  5. Сложение.

При cуффиксном инкременте:

  1. g становится операндом.
  2. g увеличивается.
  3. fun(g) вызывается с увеличенным g.
  4. Результат вызова становится операндом.
  5. Сложение.

В обоих случаях функция получает уже увеличенное g. Разница лишь в значении левого операнда:

'use strict';
function fun(arg) {
  console.log(arg);
  return arg + arg;
}
let g = 5;
console.log(g++ + fun(g));
g = 5;
console.log(++g + fun(g));
6
17
6
18
Answer 2

Зависит от синтаксиса:

++g - инкрементируется до выполнения текущего выражения.

g++ - после выполнения.

Пример:

var x = 1;
var y = x++; // y равно 1, x равно 2
var z = ++x; // z равно 3, x равно 3
Answer 3

В подтверждение слов @Эникейщик привожу несколько примеров.
В первых двух приоритета выполнения функции нет, так порядок выполнения следующий:

  • сначала операции с g в первом слагаемом (в случае g++ инкремент выполняется после сложения, но перед передачей значения в функцию),
  • потом вычисление функции,
  • сложение

А вот в 3 и 4 примерах приоритет становится очевидным.

var g = 1; 
 
function fn(g) { 
  console.log(`input parameter: ${g}`); 
  return g + g; 
} 
 
console.log(++g + fn(g)); 
 
g = 1; 
 
console.log(g++ + fn(g)); 
 
// а вот в примерах ниже уже работает приоритет function 
g = 1; 
 
console.log(fn(++g)); 
 
g = 1; 
 
console.log(fn(g++));

READ ALSO
laravel аутентификация не учитывает регистр

laravel аутентификация не учитывает регистр

Я использую стандартную аутентификацию laravelПри этом поиск пользователя осуществляется по полю login вместо поля email

134
having по двум вхожденям [дубликат]

having по двум вхожденям [дубликат]

На данный вопрос уже ответили:

159
Правильный запрос к смежным таблицам mysql php

Правильный запрос к смежным таблицам mysql php

Подскажите пожалуйста, есть 3 таблицыUsers (клиенты), company (компании), users to company (смежная таблица)

158