Почему пустой массив Array преобразует в ноль?+ [] - PullRequest
16 голосов
/ 22 июля 2010

только когда я подумал, что что-то понял в преобразовании типов в JavaScript, я наткнулся на это:

+[]; // 0
Number([]); // 0

Сначала я подумал, что мне нужно получить NaN, как если бы я попытался преобразовать пустой объект в число:

+{}; // NaN
Number({}); // NaN

Я долго об этом искал, но безуспешно ...

Может кто-нибудь объяснить мне, почему он конвертируется в 0, а не в NaN?

Это стандарт поведения?

Спасибо.

1 Ответ

22 голосов
/ 22 июля 2010

Вкратце, есть два ключевых момента:

Например,мы можем использовать объект, который определяет метод 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...