JavaScript делает забавные автоматические преобразования с объектами:
var o = {toString: function() {return "40"; }};
print(o + o);
print((o+1)+o);
print((o*2) + (+o));
напечатает:
4040
40140
120
Это потому, что +, если какой-либо из аргументов является объектами / строками, будет пытаться преобразовать все аргументы в строки, а затем объединить их. Если все аргументы являются числами, он складывает их вместе. * и унарный + конвертировать объекты в числа с помощью toString (а также valueOf, не показанного здесь).
Что делает JavaScript для оператора ++?



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Следующий код хорошо это иллюстрирует:
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
Унарный плюс преобразует объект в число и не изменяет его. a ++ сначала преобразует объект в число затем возвращает это число, а затем увеличивает число, сохраняя значение в a.
Это противоположно другому возможному решению, когда ++ сначала возвращает объект, а затем выполняет преобразование в число и увеличение.
Оператор ++ выполняет преобразование «toNumber» (в основном это комбинация правил типов и функции valueOf). В основном для любого выражения разрешения
resolveExpression++
Шаги, предпринятые JS-движком:
<temp> = toNumber(resolveExpression);
resolveExpression = <temp> + 1;
<result> = <temp>
Для неатомарных выражений разрешения, например. base.resolve++ или base["resolve"]++ и т. д. base разрешается только один раз, а затем используется повторно. В любом разумном случае это не имеет значения, однако важно, если увеличиваемое значение является объектом с реализацией valueOf, которая изменяет базовый объект.
например.
base = {};
base.value = {valueOf:function(){base = {}; return 5;}}
base.value++;
От Спецификация языка ECMAScript
11.3 Postfix Expressions
Syntax
PostfixExpression :
- LeftHandSideExpression
- LeftHandSideExpression [no LineTerminator here] ++
- LeftHandSideExpression [no LineTerminator here] --
11.3.1 Postfix Increment Operator
The production PostfixExpression : LeftHandSideExpression [no LineTerminator here] ++ is evaluated as follows:
- Evaluate LeftHandSideExpression.
- Call GetValue(Result(1)).
- Call ToNumber(Result(2)).
- Add the value 1 to Result(3), using the same rules as for the + operator (section 11.6.3).
- Call PutValue(Result(1), Result(4)).
- Return Result(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. Обновлено, чтобы отразить это.
@Mikesamuel: Ага, мне плохо. Он должен был быть в псевдокоде ... Я обновил его сейчас. Спасибо, что указали на это.
Здесь нет parseInt. Он преобразуется в число, поэтому результат может иметь дробную часть. рассмотрим x = '4.5', ++ x, и схема преобразования внутреннего числа распознает шестнадцатеричный код в строках x = '0xA', ++ x