Как понимать двойное отрицание: !! (например, в JavaScript)?
- 34,094
- 2,274
-
и в каких языках используется? – dfhsfhgfj Jan 31 '13 at 21:13
-
ассоциация: http://stackoverflow.com/questions/784929/ – Nofate Feb 27 '17 at 17:40
1 Answers
В javascript всякое значение может быть интерпретировано как Boolean. (Правила этой интерпретации довольно сложны и не вполне интуитивны.)
Если вы укажете какое-нибудь выражение там, где ожидается Boolean (например, внутри if'а), оно проинтерпретируется как Boolean, и всё. Но если вы хотите получить соответствующий Boolean (например, чтобы вернуть его из функции или присвоить другой переменной), вам нужен трюк, который заставит систему проинтерпретировать ваше выражение в булевом контексте.
Для этой цели традиционно используется двойное отрицание: первое отрицание "требует" булев контекст, так что выражение интерпретируется как Boolean, а второе отрицание "отменяет" первое.
Из документации:
Оператор отрицания: возвращает
falseесли его аргумент может быть преобразован вtrue, в противном случае возвращаетtrue.
Для справки: значения, которые в булевом контексте будут проинтерпретированы как false суть следующие:
- число
0.0 - число
NaN undefinednull- пустая строка
- ну и конечно
false
Все остальные значения будут проинтерпретированы как true.
Пример: если x -- объект или null, вместо
if (x != null)
return true;
else
return false;
можно воспользоваться изящным
return !!x;
По поводу других языков: подобный трюк нужен в основном в слабо типизированных языках вроде javascript'а, в котором значением переменной может быть и true/false, и undefined, и функция, и объект. Применение двойного отрицания гарантирует отсутствие неожиданностей в поведении полученного объекта: его тип то уж точно boolean. Однако, я встречал этот трюк и в C++ в контексте явного преобразования указателя в bool.
- 206,799
-
12
-
1Это дает какой-либо выигрыш по сравнению с return Boolean(x) или они абсолютно равноценны? – mirus Feb 01 '13 at 10:41
-
5@mirus: насколько я понимаю,
Boolean(x)то же что и!!x. Stackoverflow подсказывает, что также+x-- то же, что иNumber(x). (Автор ответа считает такие паттерны хаком.) Заметьте, чтоnew Boolean(x)-- не то же самое:
– VladD Feb 01 '13 at 11:09typeof(!!x) === "boolean" typeof(Boolean(x)) === "boolean" typeof(new Boolean(x)) === "object" -
3да с new Boolean ваще есть прикол, это объект и получаем что new Boolean(false) если проверить в условие вернет true т.е var v = new Boolean(false); if(v) alert('во как'); – Ильяс Feb 06 '13 at 05:35
-
2@ilyas: Так и есть: тип
new Boolean(false)-- объект, он будет интерпретироваться как false только еслиnull. А вот типBoolean(false)-- boolean. – VladD Feb 06 '13 at 16:01