Я должен был записать стандартную программу, которая увеличивает значение переменной 1, если ее тип number
и присваивает 0 переменной в противном случае, где переменная первоначально null
или undefined
.
Первая реализация была v >= 0 ? v += 1 : v = 0
потому что я думал что-либо не, число сделает ложь арифметического выражения, но это было неправильно с тех пор null >= 0
оценен к истинному. Затем я учился null
ведет себя как 0, и следующие выражения все оценены к истинному.
null >= 0 && null <= 0
!(null < 0 || null > 0)
null + 1 === 1
1 / null === Infinity
Math.pow(42, null) === 1
Конечно, null
не 0. null == 0
оценен ко лжи. Это делает на вид тавтологическое выражение (v >= 0 && v <= 0) === (v == 0)
ложь.
Почему null
как 0, хотя это не на самом деле 0?
Ваш настоящий вопрос, похоже, таков:
Почему:
null >= 0; // true
Но:
null == 0; // false
На самом деле происходит то, что Оператор "больше или равно" (> =
), выполняет приведение типа ( ToPrimitive
) с типом подсказки Number.
, фактически все реляционные операторы имеют такое поведение.
null
особым образом обрабатывается оператором Equals ( ==
). Вкратце, он только приводит к к undefined
:
null == null; // true
null == undefined; // true
Значение, такое как false
, ''
, '0 '
и []
подлежат приведению числового типа, все они приводятся к нулю.
Вы можете увидеть внутренние детали этого процесса в Алгоритме сравнения абстрактного равенства и Алгоритме абстрактного реляционного сравнения .
В сводке:
Реляционное сравнение: если оба значения не относятся к типу String, ToNumber
вызывается на обоих. Это то же самое, что и добавление +
впереди, которое для нуля приводит к 0
.
Сравнение равенства: вызывает ToNumber
только для строк, чисел и логических значений.