На самом деле, чтобы понять, почему вы получаете этот результат, вы должны подумать, как оценивается выражение (т.е. в каком порядке?). Если мы увидим ваше первое выражение:
const v = (! + [] + []);
мы можем видеть, что существует один логический оператор (логическое НЕ !
), один унарный оператор (+
) и один арифметический оператор, фактически сложение +
. Если мы примем во внимание порядок вычисления этого выражения, мы можем написать его так:
const v = ( (!(+[])) + [] );
Теперь первое вычисленное здесь выражение - +[]
, и из документации оператора унарный плюс вы получите:
Унарный оператор плюс предшествует своему операнду и вычисляет его операнд, но пытается преобразовать его в число, если его еще нет ...
На самом деле предыдущая оценка приводит к 0
(приведение происходит, когда пустой массив приводится к числовому типу), как вы можете проверить в следующем примере:
Итак, теперь выражение сокращено до
const v = ( (!0) + [] );
Снова, читая некоторую документацию этого логического оператора , который вы можете найти:
Возвращает false, если его единственный операнд может быть преобразован в true; в противном случае возвращает true.
Итак, !0
уменьшен до true
(другое принуждение происходит, когда число ноль приводится к логическому типу), как вы можете проверить в следующем примере:
Теперь у нас есть следующее выражение, где в игру вступает оператор добавление :
const v = ( true + [] );
Оператор сложения создает сумму числовых операндов или конкатенации строк.
В этом случае оператор выполняет конкатенацию строк, поскольку операнды не являются числами. Итак, вот где новое приведение (в основном неявное приведение типов) происходит снова, потому что ему нужно преобразовать оба операнда в строки:
true
преобразуется в строку "true"
с использованием метода toString()
типа Boolean .
- и пустой массив
[]
преобразуется в пустую строку ""
с использованием доступного метода toString()
типа Array .
И, наконец, наше выражение сводится к:
const v = "true" + ""; // or simply "true".
const v = (! + [] + []);
console.log("value: " + v, "type: " + typeof(v));
Второе выражение теперь должно быть легко проанализировано для вас, поскольку оно является упрощенной версией первого.