Приведение типов (детально) - Max-Starling/Notes GitHub Wiki
Приведение типов
// Операторы + / - читаются слева-направо. Оператор + по возможности приводит
// к строке, а оператор - всегда к числу.
// Для оператора +: {} + что-то (за исключением объекта) --> число, остальное
// приводится к строке.
// Для оператора -: всё приводится к числу. Если имеется объект, undefined
// или строка, имеющая несвойственные для числа символы, получаем NaN.
// Так как идёт приведение к числу, {} ~ NaN, [] ~ 0, null ~ 0, undefined ~ NaN.
{} + "" --> 0 / -0
{} + "8" --> 8 / -8
{} + "8y" --> NaN / NaN
{} + "" + [] --> "0" / -0
{} + null -> 0 / 0
{} + undefined -> NaN / NaN
{} + [] --> 0 / -0
{} + [] + "" --> "0" / -0
{} + [] + "8" --> "08" / -8
{} + [] + "8y" --> "08y" / NaN
// Также есть баг с {} + ... + {}, при котором по логике вещей должно быть приведение
// к числу, но его не происходит. Оператор - вернёт NaN во всех случаях.
{} + {} --> "[object Object][object Object]"
{} + [] + {} --> "[object Object][object Object]"
{} + 8 + {} --> "[object Object]8[object Object]"
{} + {} + {} --> "[object Object][object Object][object Object]"
{} + {} + [] + {} --> "[object Object][object Object][object Object]"
// Тем не менее, если начальный или конечный операнды не являются объектами, всё
// отрабатывает так, как ожидается.
{} + {} + "" --> "NaN"
{} + {} + [] --> "NaN"
{} + {} + 0 --> NaN
{} + {} + "8" --> "NaN8"
{} + 8 + {} + [] --> "8[object Object]"
{} + undefined + {} + [] --> "NaN[object Object]"
// Обычно {} ~ "[object Object]", [] ~ "", null ~ 0, boolean ~ 0 / 1
[] + [] --> "" / 0
[] + "" --> "" / 0
[] + {} --> "[object Object]" / NaN
"" + [] --> "" / 0
"8" + [] --> "8" / 8
"8y" + [] --> "8y" / NaN
"" + {} --> "[object Object]" / NaN
"8" + {} --> "8[object Object]" / NaN
"" + {} + [] --> "[object Object]" / NaN
"" + [] + {} --> "[object Object]" / NaN
0 + "" --> "0" / 0
0 + {} --> "0[object Object]" / NaN
0 + {} + [] --> "0[object Object]" / NaN
0 + [] --> "0" // 0
0 + [] + {} --> "0[object Object]" / NaN
null + 8 --> 8 / -8
false + true --> 1 / -1
// Операторы && / || читаются cлева-направо. Оператор && прерывается на первом false,
// оператор || прерывается на первом true.
// Правила: 0 ~ false, остальные числа ~ true, "" ~ false, "..." ~ true (включая "0"),
// {} ~ true, [] ~ true, null ~ false, undefined ~ false.
1 && 3 --> 3 / 1
1 && 3 && null --> null / 1
1 && 3 && null && undefined --> null / 1
1 && 3 && null && undefined && 4 --> null / 1
0 && 3 && null && true --> 0 / 3