Все значения Falsey в JavaScript
Какие значения в JavaScript являются "ложными", что означает, что они оцениваются как ложные в таких выражениях, как if(value)
, value ?
а также !value
?
Есть некоторые дискуссии о назначении значений Falsey для переполнения стека, но нет исчерпывающего полного ответа, в котором перечислены все значения Falsey.
Я не смог найти полный список в Справочнике по MDN JavaScript, и с удивлением обнаружил, что лучшими результатами при поиске полного, достоверного списка значений Falsey в JavaScript были статьи блога, некоторые из которых имели очевидные упущения (например, NaN
), и ни один из которых не имел такого формата, как переполнение стека, где можно было бы добавить комментарии или альтернативные ответы, чтобы указать на причуды, неожиданности, упущения, ошибки или предостережения. Таким образом, казалось, что имеет смысл сделать один.
3 ответа
Ложные значения в JavaScript
false
0
и другие формы числового нуля, как-0
,0.0
а также0x0
( кредит RBT для шестнадцатеричной формы)""
,''
а также``
- строки длиной 0null
undefined
NaN
document.all
(только в браузерах HTML)- Это странно.
document.all
является фальшивым объектом, сtypeof
какundefined
, Это была проприетарная функция Microsoft в IE до IE11, и она была добавлена в спецификацию HTML как "преднамеренное нарушение спецификации JavaScript", чтобы сайты, написанные для IE, не ломались, например, при попытке доступа.document.all.something
; это ложно, потому чтоif (document.all)
Раньше был популярным способом обнаружения IE, перед условными комментариями. См. Почему document.all ложно? для деталей
- Это странно.
"Falsey" просто означает, что JavaScript является внутренним ToBoolean
функция возвращает false
, ToBoolean
лежит в основе !value
, value ? ... : ...;
а также if (value)
, Вот его официальная спецификация (рабочий проект 2018 года) (единственное изменение с самой первой спецификации ECMAscript в 1997 году - это добавление символов ES6, которые всегда правдивы):
Сравнения с ==
(слабое равенство)
Стоит говорить о слабых сравнениях с ложными ценностями ==
, который использует ToNumber()
и может вызвать некоторую путаницу из-за основных различий. Они эффективно образуют три группы:
false, 0, -0, "", ''
все соответствуют друг другу с==
- например
false == ""
,'' == 0
и поэтому4/2 - 2 == 'some string'.slice(11);
- например
null, undefined
совпадает с==
- например
null == undefined
ноundefined != false
- Стоит также отметить, что пока
typeof null
возвращается'object'
,null
это не объект, это давняя ошибка / причуда, которая не была исправлена для обеспечения совместимости. Это не настоящий объект, а объекты правдивые (за исключением этого "преднамеренного нарушения").document.all
когда Javascript реализован в HTML)
- например
NaN
ничего не соответствует, с==
или же===
даже не сама- например
NaN != NaN
,NaN !== NaN
,NaN != false
,NaN != null
- например
С "строгим равенством" (===
) таких группировок нет. Только false
===
false
,
Это одна из причин, по которой многие разработчики и многие руководства по стилю (например, https://standardjs.com/) предпочитают ===
и почти никогда не пользуюсь ==
,
Истинные ценности, которые на самом деле == false
"Правда" просто означает, что внутренний JavaScript ToBoolean
функция возвращает true
, Причудливый Javascript, который нужно знать (и еще одна веская причина, чтобы предпочесть ===
над ==
): значение может быть правдивым (ToBoolean
возвращается true
), но также == false
,
Ты можешь подумать if (value && value == false) alert('Huh?')
это логическая невозможность, которая не может произойти, но это произойдет для:
"0"
а также'0'
- это непустые строки, которые являются правдой, но Javascript==
сопоставляет числа с эквивалентными строками (например,42 == "42"
). поскольку0 == false
, если"0" == 0
,"0" == false
,new Number(0)
а такжеnew Boolean(false)
- это объекты, которые правдивы, но==
видит их ценности, которые== false
,0 .toExponential();
- объект с числовым значением, эквивалентным0
- Любые подобные конструкции, которые дают вам ложно-выравнивающее значение, заключенное в тип, который является правдивым
[]
,[[]]
а также[0]
(спасибо cloudfeet за ссылку на таблицу равенства JavaScript)
Еще несколько правдивых ценностей
Это всего лишь несколько ценностей, которые некоторые люди могут считать ложными, но на самом деле они правдивы.
-1
и все ненулевые отрицательные числа' '
," "
,"false"
,'null'
... все непустые строки, включая строки, которые являются только пробеламиЧто-нибудь от
typeof
, который всегда возвращает непустую строку, например:typeof null
(возвращает строку'object'
из-за давней ошибки / причуды)typeof undefined
(возвращает строку'undefined'
)
Любой объект (кроме этого "преднамеренного нарушения"
document.all
в браузерах; помни этоnull
на самом деле не является объектом, несмотря наtypeof
предлагая иначе). В том числе:{}
[]
function(){}
или же() => {}
(любая функция, включая пустые функции)Error
и любой случайError
- Любое регулярное выражение
- Все, что создано с
new
(в том числеnew Number(0)
а такжеnew Boolean(false)
)
- Любой символ
true
, 1
, "1"
а также [1]
вернуть true
по сравнению друг с другом с ==
,
Не забывайте о непустой строке "false"
который оценивает true
Просто чтобы добавить в список ложных значений @user568458:
В дополнение к целому числу 0 десятичное число 0, 0, 0, 00 или любое такое нулевое число также является ложным значением.
var myNum = 0.0; if(myNum){ console.log('I am a truthy value'); } else { console.log('I am a falsy value'); }
Вышеупомянутые фрагменты кода
I am a falsy value
Аналогично, шестнадцатеричное представление числа 0 также является ложным значением, как показано в следующем фрагменте кода:
var myNum = 0x0; //hex representation of 0 if(myNum){ console.log('I am a truthy value'); } else { console.log('I am a falsy value'); }
Над фрагментом кода снова печатает
I am a falsy value
,
В дополнение к теме, с ES2020 у нас есть новое значение, которое является ложным, это ноль BigInt (0n):
0n == false // true
-0n == false // true
Таким образом, теперь у нас есть всего 7 "ложных" значений (не включая document.all, упомянутый выше пользователем, поскольку он является частью DOM, а не JS).