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

Как приращение postfix работает, когда он встречает оператор добавления (+) в JavaScript?

Прежде всего, я знаю, что выражения, о которых говорилось позже, имеют side-effects и не должны использоваться в рабочей среде. Я просто хочу понять через них JavaScript. Все они тестируются под Chrome.

var a = 42;
var b = "42";
a + ++b; // result is 85 

Вот мое понимание a + ++b,

Prefix Increment (++) (приоритет 15) имеет более высокий приоритет, чем Addition(+) (приоритет 13) в соответствии с приоритетом оператора. ++b можно разобрать var ToNumber(GetValue(expr)) до 43, обратитесь к 12.5.7 Prefix Increment Operator. Тогда результатом a + 43 может быть 85.

Однако

var a = 42;
var b = "42";
a++ + b; // "4242"

Почему результатом a++ + b является "4242"?

Я пытаюсь понять результат "4242", кажется, что a++ возвращает 42 во-первых, тогда для 42 + '42' 42 будет '42' var ToString(), во-первых, обратитесь к 12.7.3 The Addition operator ( + ). то результатом может быть "4242".

Но, похоже, это нарушает правило: Postfix increment (приоритет 16) выше Addition (приоритет 13)???

var a = 42;
var b = "42";
a +++b; // "4242" 

Как анализируется a +++b;?

4b9b3361

Ответ 1

Ха-ха, хитрый!

Приращение post-fix возвращает одно и то же значение, а затем увеличивает эту переменную. Это поведение по умолчанию на всех языках, которые я знаю.

Итак, когда вы это делаете ( предупреждение:, это не допустимое выражение, просто чтобы показать эту идею):

42++ + "42"

Что действительно происходит:

  • Первая 42 возвращается оператором ++
  • Затем 42 увеличивается до 43
  • Тогда 42 (результат результата выражения) принудительно вставляется в строку
  • Затем два операнда конкатенируются

Изменить # 1:

Если вы выполните:

var a = 42;
var b = "42";
a + b++; // result is 84

Проверьте это!

Изменить # 2:

Итак, мы заключаем, что ваш вопрос не имеет ничего общего с приоритетом оператора (:

Ответ 2

Существует разница в пост и предварительном приращении в javascript, а затем на других языках. То есть эти операторы могут быть разделены одним пространством из операнда. Например:

var a = 42;
++ a;

Обратите внимание на пространство между ++ и a, это также работает с a ++
поэтому, когда javascript начинает анализировать утверждения, он принимает операнд или оператор и сохраняет его в своем стеке и находит любую возможность использовать его. Надеюсь, вы знаете, как инструкции разбора языка, слева направо или справа налево. Javascript анализирует его слева направо.
Итак, когда вы написали a +++b, он начал синтаксический анализ слева,

Найдено: нажмите a в стеке; стек: [a]
  Найдено +: push + in stack; stack: [a, +]
  Найдено +: pop + и a из стека и примените операнд и нажмите   результат в стеке (теперь стек имеет только память, а не ++, потому что   поэтапного увеличения); stack [a]
  Найдено +: нажмите на стек; stack: [a, +]
  Найдено b: pop + и a из стека, примените операнд и нажмите результат на стек; стек: [b]

Больше операндов или операторов, поэтому он дает результат, который равен a+b, а также увеличивает его после него в результате поэтапного приращения на a, если вы хотите увеличить b до добавления, вы можете попробовать следующее:

a + ++b

это разделит + из ++, теперь javascript знает, где применять приращение.

Ответ 3

Конечно, операторы increment/декременты - операторы унарные - имеют приоритет над оператором + (добавление/конкатенация) двоичный, но я думаю, что интересная проблема здесь принуждение. Позвольте мне объяснить:

Почему результат ++ + b равен 4242?

(a - число 42, а b - строка '42')

Это потому, что когда вы применяете оператор increment к строке с числовым значением ('42'), результат принуждается к числу (42).

Итак, теперь мы остаемся с выражением number + string (42 + '42'): В этом случае оператор + будет конкатенатировать (принудительное число 42 в строку "42" и в результате получается строка "4242" ").

С другой стороны: в первом примере a + ++b (a - номер 42, а b - строка '42') - b будет принудительно введено в число после того, как инкремент оставит нас с number + number (42 + 43) - поэтому оператор + будет выполнять addition вместо конкатенации (42 + 43 = 85)

Относительно следующего вопроса:

Как работает a +++ b; анализироваться?

Так как законно разделять переменную и инкрементный оператор с пространством, поэтому синтаксический анализатор будет смотреть на a +++b и сначала увидеть a++.

Кроме того, поскольку оператор + не требует пробелов между обоими операндами, синтаксический анализатор корректно отделяет операнды a++ и b оператором +. Итак, a +++b; будет анализироваться как a++ + b

Ответ 4

@zangw нет ничего подобного ++ имеет более высокий приоритет, чем+. ++ b является оператором pre increment и + является арифметикой. ++ b означает сначала изменить значение операнда, а затем использовать его, противоречащее a ++. ++ всегда приходит с одним операндом, а + - между двумя операндами, а позже - экспериментом. надеюсь, что у вас есть?

Ответ 5

Хороший вопрос, проверьте этот стандарт ecma 12.7.3.1 (шаг 11)

11. If Type(lprim) is String or Type(rprim) is String, then
   a. Let lstr be ToString(lprim).
   b. ReturnIfAbrupt(lstr).
   c. Let rstr be ToString(rprim).
   d. ReturnIfAbrupt(rstr).
   e. Return the String that is the result of concatenating lstr and rstr

если любой из операторов string, то оба они преобразуются в строку, а затем выполняется конкатенация.

Ответ 6

Это фактически не имеет никакого отношения к приоритету оператора; это связано с лексированием/разбором, которое происходит задолго до того, как будет применена любая концепция, например, приоритет оператора. Лексер для JavaScript, как и многие другие языки, является "жадным", что означает, что выбор "+" и "++" всегда будет выбирать более длинный символ.

Ответ 7

Хороший вопрос, но вот ответ:).

    var a = 42;
    var b = "42";
    console.log(a +++b); // "4242" 
    console.log(a);
    console.log(b);
    console.log('A is 43 now... so postfix on A, then + B');

Ответ 8

Часть имени post принадлежит не только из физического присутствия оператора (перед операндом или после операнда), но и с момента фактического обновления переменной.

Приоритет Postfix определяется здесь как:

[Оператор increment (++),] Если используется постфикс, с оператором после операнда (например, x ++), тогда он возвращает значение до приращения.

Следовательно, он возвращает значение в конкатенацию, а затем увеличивает эту переменную. То есть, пост-инкрементированная переменная обновляется после возвращения исходного значения в операцию добавления.

Ответ на ваш вопрос заключается в понимании того, когда переменная обновляется.

Приоритет операторов имеет смысл, потому что постфикс все еще оценивается первым, а затем дополнение осуществлен. Однако переменная постфикса не обновляется до тех пор, пока значение не будет возвращено в дополнение. Следовательно, результатом является "4242".