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

Не могу объяснить эти результаты

Может кто-нибудь объяснить мне, почему эти результаты?

enter image description here

Я знаю, что это не настоящая проблема, но мне интересно узнать.

Спасибо

4b9b3361

Ответ 1

Это потому, что + предназначено для добавления чисел и строк, это также унарный оператор. Это также потому, что {} - это пустой объект и блок-оператор.

Я могу это объяснить.

[] + {}

Оба преобразуются в строки.

[].toString() + {}.toString()

[].toString() совпадает с [].join(''), а {}.toString() - '[object Object]', поэтому первый - [object Object].

Второй - более запутанный.

{} + []

{} здесь не интерпретируется как объект, интерпретируется как пустой блок. Таким образом, код внутри запускается. Там нет ничего внутри, поэтому он ничего не делает, затем выполняется следующее утверждение: +[]. Это преобразует массив в int, который сначала преобразует его в строку, чем его.

{} + [] => +[] => +([].toString()) => 0

Если вы введете {} в скобки, это будет то же самое, что и первый.

({}) + [] => '[object Object]'

Ответ 2

Из здесь, относящийся к this

  • [] + []

    При использовании оператора сложения правый и правый операнды сначала преобразуются в примитивы (§11.6.1). Согласно §9.1, преобразование объекта (в данном случае массива) в примитив возвращается его значение по умолчанию, которое для объектов с допустимым методом toString()является результатом вызова object.toString() (§8.12.8). Для массивы это то же самое, что и вызов array.join() ([§15.4.4.2] [4]). Объединение пустого массива приводит к пустой строке, поэтому шаг 7 оператор сложения возвращает конкатенацию двух пустых строк, который является пустой строкой.

  • [] + {}

    Подобно [] + [], оба операнда сначала преобразуются в примитивы. Для "Объектных объектов" (§15.2) это снова является результатом вызов object.toString(), который для объектов с ненулевым, не undefinedявляется "[object Object]" ([§15.2.4.2] [5]).

  • {} + []

    {} здесь не анализируется как объект, а вместо этого как пустой блок ([§12.1] [6]), по крайней мере, пока вы не заставляете это выражение будет выражением, но об этом позже). Возврат значение пустых блоков пусто, поэтому результатом этого утверждения является так же, как +[]. Унарный оператор + ([11.4.6] [7]) возвращает ToNumber(ToPrimitive(operand)). Как мы уже знаем, ToPrimitive([]) - пустая строка, и согласно [§9.3.1] [8] ToNumber("") равно 0.

  • {} + {}

    Как и в предыдущем случае, первый {} анализируется как блок с пустым возвращаемым значением. Опять же, +{} совпадает с ToNumber(ToPrimitive({})), а ToPrimitive({}) - "[object Object]" (см. [] + {}). Итак, чтобы получить результат +{}, мы должны примените ToNumber к строке "[object Object]". Когда шагов из [§9.3.1] [9], получаем NaN в результате:

    Если грамматика не может интерпретировать String как расширение StringNumericLiteral, то результат [ToNumber] [10] NaN.

  • Array(16).join("wat" - 1)

    В соответствии с [§15.4.1.1] [11] и [§15.4.2.2] [12], Array(16) создает новый массив длиной 16. Чтобы получить значение аргумента для соединения, [§11.6.2] [13] шаги №5 и №6 показывают, что мы должны преобразовать оба операндов к числу с помощью ToNumber. ToNumber(1) является просто 1 ([§9.3] [14]), тогда как ToNumber("wat") снова NaN в соответствии с [§9.3.1] [15]. Следуя шагу 7 пункта [11.6.2] [16], [§11.6.3] [17] диктует, что

    Если один из операндов NaN, результат NaN.

    Итак, аргумент Array(16).join равен NaN. Следуя §15.4.4.5 (Array.prototype.join), мы должны называть ToString аргументом, который является "NaN" ([§9.8.1] [18]):

    Если m NaN, верните строку "NaN".

    Следуя шагу 10 из [15.4.4.5] [19], мы получаем 15 повторений конкатенации "NaN" и пустую строку, которая равна результату вы видите. При использовании "wat" + 1 вместо "wat" - 1 в качестве аргумент, оператор сложения преобразует 1 в строку вместо преобразование "wat" в число, поэтому оно эффективно вызывает Array(16).join("wat1").