JavaScript прекрасен. Но в нем есть некоторое количество так называемых особенностей, которые делают его чуть менее прекрасным, чем хотелось бы. Например, приведение типов.
[]+[]
> ""
[]+{}
> "[object Object]"
{}+[]
> 0
{}+{}
> NaN
Почему так? Это кажется бредом, пока не разберешься с системой типов в JavaScript. Ладно-ладно, это кажется бредом в любом случае, но тем не менее попробуем хоть чуть разобраться.
Самое главное, что нужно знать — операция +
работает только с примитивными типами. Т.е. что бы вы ни написали, выражение будет приведено к этим типам. Даже больше: если хотя бы один операнд — строка, то и результат будет строкой. Поэтому, чтобы понять причину происходящего выше, нужно узнать, как объекты и массивы приводятся к примитивным типам.
У каждого объекта и массива (ведь массив тоже объект) есть 2 метода: valueOf
и toString
. И именно они будут использоваться для преобразования типов. Сначала интерпретатор вызывает valueOf
, и если он вернул не примитивное значение, то вызывается toString
. Теперь нужно выяснить, что же возвращают эти методы у {}
и []
.
console.log({}.valueOf()); // Возвращает себя
console.log([].valueOf()); // [] (тоже себя)
console.log([].toString()); // ""
console.log({}.toString()); // "[object Object]"
Засада. Каким образом {}+[]
дает 0, ведь по логике должно быть "[object Object]"
? Ковыряние в спецификации пока ни к чему не привело. Если кто знает правильный ответ, не томите, поделитесь наблюдениями.
Ну и совсем напоследок видео, из-за которого я начал разбираться в этой теме. Посмотрите, не пожалеете.
UPD: Исправлен верхний листинг.
UPD2: Разгадка.
Хочется что-то добавить или сказать? Я всегда рад обсудить. Пишите на me@dikmax.name.