Вкратце, есть два ключевых момента:
Например,мы можем использовать объект, который определяет метод toString
и возвращает пустую строку для получения эквивалентного результата:
var obj = { toString: function () { return "";} };
+obj; // 0
Number(obj); // 0
Это поведение полностью стандартное.
Теперь длинный ответ:
Оба оператора унарный плюс и конструктор Number
, вызываемые как функция , внутренне используют абстрактную операцию ToNumber
.
ToNumber
будет использовать еще две внутренние операции: ToPrimitive
и [[DefaultValue]]
.
Когда применяется операция ToNumber
для объекта, такого как пустой массив в вашем примере, он вызывает операцию ToPrimitive
, чтобы получить репрезентативное примитивное значение и снова вызвать ToNumber
, используя это значение [1] .
Операция ToPrimitive
получает два аргумента: значение (которое является вашим объектом массива) и тип подсказки, который в данном случае является «числом», поскольку мы хотим выполнить числовое преобразование.
ToPrimitive
вызывает внутренний метод [[DefaultValue]]
, также с типом подсказки «Number».
Теперь, поскольку мы используем тип подсказки «Number», внутренний метод [[DefaultValue]]
теперь попытается сначала вызвать *Метод 1060 * для объекта.
Объекты массива не имеют определенного метода valueOf
, метод унаследован от Object.prototype.valueOf
, и этот метод просто возвращает ссылкусамому объекту .
Поскольку метод valueOf
не привел к примитивное значение , теперь вызывается метод toString
, и он генерирует пустую строку (которая является примитивным значением), затем операция ToNumber
попытается выполнить преобразование String-Number и, наконец, завершитсяс 0
[1] .
Но теперь вы можете задаться вопросом, почему пустая строка приводит к нулю?
+""; // 0
Существует полная грамматика, котораяиспользуется, когда внутренняя операция ToNumber
применяется к типу String , производному StringNumericLiteral
.
Он имеет некоторые различия между NumericLiteral, и одно из этих отличий состоит в том, что:
StringNumericLiteral, который пуст или содержит только пробел, преобразуется в + 0.