Вот список объяснений результатов, которые вы видите (и должен их видеть). Ссылки, которые я использую, из стандарта ECMA-262 .
[] + []
toString()
методом является результатом вызова object.toString()
( §8.12.8 ). Для массивов это то же самое, что и вызов array.join()
( §15.4.4.2 ). Объединение пустого массива приводит к пустой строке, поэтому шаг # 7 оператора сложения возвращает конкатенацию двух пустых строк, которая является пустой строкой. [] + {}
[] + []
оба операнда сначала преобразуются в примитивы. Для «Объектных объектов» (§15.2) это снова является результатом вызова object.toString()
, который для непустых не неопределенных объектов является "[object Object]"
( §15.2.4.2 ). {} + []
{}
не анализируется как объект, а вместо этого как пустой блок ( §12.1 , по крайней мере, до тех пор, пока вы не заставляете это выражение быть выражением, но об этом позже). Возвращаемое значение пустых блоков пуст, поэтому результат этого оператора совпадает с +[]
. Унарный +
оператор ( §11.4.6 ) возвращает ToNumber(ToPrimitive(operand))
. Как мы уже знаем, ToPrimitive([])
является пустой строкой, и согласно §9.3.1 , ToNumber("")
равен 0. {} + {}
{}
анализируется как блок с пустым возвращаемым значением. Опять же, +{}
совпадает с ToNumber(ToPrimitive({}))
, а ToPrimitive({})
- "[object Object]"
(см. [] + {}
). Поэтому, чтобы получить результат +{}
, мы должны применить ToNumber
к строке "[object Object]"
. Следуя шагам из §9.3.1 , мы получаем NaN
в результате: если грамматика не может интерпретировать строку как расширение StringNumericLiteral , то результат ToNumber - NaN. Array(16).join("wat" - 1)
Array(16)
создает новый массив с длиной 16. Чтобы получить значение аргумента для соединения, §11.6.2 шаги # 5 и # 6 показывают, что нам нужно преобразовать оба операнда в число, используя ToNumber
. ToNumber(1)
является просто 1 ( §9.3 ), тогда как ToNumber("wat")
снова NaN
в соответствии с §9.3.1 . Следуя шагу 7 из §11.6.2 , §11.6.3 диктует, что если любой из операндов равен NaN, результатом является NaN. Поэтому аргументом Array(16).join
является NaN
. Следуя § 15.4.4.5 (Array.prototype.join
), мы должны называть ToString
аргументом, который является "NaN"
( §9.8.1 ): если m является NaN, возвращает строку "NaN"
. Следуя шагу 10 из §15.4.4.5 , мы получаем 15 повторений конкатенации "NaN"
и пустой строки, что равно результату, который вы видите. При использовании параметра "wat" + 1
вместо "wat" - 1
в качестве аргумента оператор сложения преобразует 1
в строку вместо преобразования "wat"
в число, поэтому он эффективно вызывает Array(16).join("wat1")
. Что касается того, почему вы видите разные результаты для случая {} + []
: при использовании в качестве аргумента функции вы вынуждаете оператор быть ExpressionStatement , что делает невозможным синтаксический анализ {}
как пустой блок, поэтому вместо этого он анализируется как пустой литерал объекта.
Это зависит от провайдера, но в большинстве случаев это действительно до тех пор, пока владелец аккаунта не отменяет ваш доступ.
Например, Twitter - срок его действия не истекает, но пользователь может отозвать ваш доступ.