Операторы if
и while
и оператор ?
используют значения истинности, чтобы определить, какую ветвь кода следует запустить. Например, нулевые и NaN числа и пустая строка являются ложными, но другие числа и строки являются истинными. Объекты имеют значение true, но неопределенное значение и null
имеют значение false.
Оператор двойного отрицания !!
вычисляет истинное значение значения. На самом деле это два оператора, где !!x
означает !(!x)
и ведет себя следующим образом:
- Если
x
является ложным значением, !x
равно true
, а !!x
равно false
.
- Если
x
- истинное значение, !x
- false
, а !!x
- true
.
При использовании на верхнем уровне логического контекста (if
, while
или ?
) оператор !!
по поведению является запретным. Например, if (x)
и if (!!x)
означают одно и то же.
Практическое использование
Однако он имеет несколько практических применений.
Одно из применений - это сжатие с потерями объекта до его истинного значения, чтобы ваш код не содержал ссылку на большой объект и не поддерживал его. Назначение переменной !!some_big_object
вместо some_big_object
позволяет ее использовать для сборщика мусора. Это полезно в случаях, когда создается либо объект, либо ложное значение, такое как null
, или неопределенное значение, такое как обнаружение функции браузера.
Другое использование, о котором я упомянул в ответе о соответствующем операторе C !!
, связано с инструментами "lint", которые ищут общие опечатки и диагностику печати. Например, как в C, так и в JavaScript несколько общих опечаток для логических операций приводят к другому поведению, вывод которого не совсем как логический:
if (a = b)
- присвоение, за которым следует значение истинности b
; if (a == b)
- сравнение на равенство.
if (a & b)
- побитовое И; if (a && b)
- это логическое И. 2 & 5
- это 0
(ложное значение); 2 && 5
верно.
Оператор !!
заверяет инструмент lint, что вы написали именно то, что вы имели в виду: выполните эту операцию, а затем получите истинное значение результата.
Третье применение - создание логического XOR и логического XNOR. И в C, и в JavaScript a && b
выполняет логическое И (истина, если обе стороны верны), а a & b
выполняет побитовое И. a || b
выполняет логическое ИЛИ (true, если хотя бы одно из них истинно), а a | b
выполняет побитовое ИЛИ. Существует побитовое XOR (исключающее ИЛИ) как a ^ b
, но нет встроенного оператора для логического XOR (true, если истинна только одна сторона). Например, вы можете разрешить пользователю вводить текст точно в одно из двух полей. Что вы можете сделать, так это преобразовать каждое значение в истинное и сравнить их: !!x !== !!y
.