Как JavaScript обрабатывает оператор ++?
-
23-08-2019 - |
Вопрос
JavaScript выполняет обалденные автоматические преобразования с объектами:
var o = {toString: function() {return "40"; }};
print(o + o);
print((o+1)+o);
print((o*2) + (+o));
будет печатать:
4040
40140
120
Это связано с тем, что +, если какой-либо из аргументов является объектами / строками, попытается преобразовать все аргументы в строки, а затем объединить их.Если все аргументы являются числами, это суммирует их вместе.* и унарный + преобразуйте объекты в числа, используя toString (а также valueOf, здесь не показано).
Что JavaScript делает для оператора ++?
Решение
От Спецификация языка ECMAScript
11.3 Постфиксные выражения
Синтаксис
Постфиксное выражение :
- Левостороннее выражение
- LeftHandSideExpression [здесь нет определения строки] ++
- LeftHandSideExpression [здесь нет определения строки] --
11.3.1 Оператор постфиксного приращения
Производство Постфиксное выражение :LeftHandSideExpression [здесь нет определения строки ] ++ оценивается следующим образом:
- Оцените выражение LeftHandSideExpression.
- Вызовите GetValue(Результат(1)).
- Номер вызова (результат(2)).
- Добавьте значение 1 к результату (3), используя те же правила, что и для оператора + (раздел 11.6.3).
- Вызовите PutValue(Результат(1), Результат(4)).
- Возвращает результат (3).
Это псевдо- javascript код того, как работает postInc:
function postInc(a) {
var x = +a; // Converts a to a number, Section 11.4.6 Unary + Operator
a = x + 1;
return x;
}
Редактировать:Как микесамуэль сказал:это не parseInt.Обновлено, чтобы отразить это.
Другие советы
Следующий код хорошо иллюстрирует это:
var a = {toString: function() {return "40"; }};
nl(typeof a);
nl(typeof +a);
nl(typeof a);
nl(typeof (a++));
nl(a);
nl(typeof a);
Результатом является:
object
number
object
number
41
number
Unary plus преобразует объект в число и не изменяет его.a ++ сначала преобразует объект в число, затем возвращает этот номер, а затем увеличивает число, сохраняя значение в a.
Это противоречит другому возможному решению, где a ++ сначала возвращает объект, а затем выполняет преобразование в число и приращение.
В ++
operator выполняет преобразование "ToNumber" (в основном это комбинация правил типа и функции valueOf).В основном для любого выражения разрешения
resolveExpression++
Шаги , предпринятые движком JS, заключаются в следующем
<temp> = toNumber(resolveExpression);
resolveExpression = <temp> + 1;
<result> = <temp>
Для неатомных разрешающих выражений, например. base.resolve++
или base["resolve"]++
, и т.д. base
разрешается только один раз, а затем используется повторно.В любом нормальном случае это не имеет значения, однако важно, если увеличиваемое значение является объектом со значением реализации, которое изменяет базовый объект.
например.
base = {};
base.value = {valueOf:function(){base = {}; return 5;}}
base.value++;