Переменные JavaScript свободно / динамически типизируются, и язык не заботится о том, как значение объявляется или изменяется.
2017.08.22: эта статья была обновлена, чтобы отразить текущее состояние экосистемы JavaScript.
let x;
x = 1; // x is a number
x = '1'; // x is a string
x = [1]; // x is an array
Кажущиеся разными значения равны true
==
// all true
1 == '1';
1 == [1];
'1' == [1];
Более очевидный false
===
// all false
1 === '1';
1 === [1];
'1' === [1];
Внутренне JavaScript устанавливает значение одного из шести примитивных типов данных:
- Не определено (переменная без определенного значения)
- Null (одно нулевое значение)
- Логическое (истинное или ложное)
- Число (это включает в себя
Infinity
NaN
- Строка (текстовые данные)
- Symbol (уникальный и неизменный примитив, новый для ES6 / 2015)
Все остальное является объектом — включая массивы.
Правда и ложь
Как и тип, каждому значению также присуще логическое значение, обычно известное как истинное или ложное . Некоторые правила немного причудливы, поэтому понимание концепций и их влияние на сравнение помогают при отладке приложений JavaScript.
Следующие значения всегда ложны :
-
false
-
0
-
''
""
-
null
-
undefined
-
NaN
Все остальное правдиво . Это включает:
-
'0'
-
'false'
-
[]
-
{}
-
function(){}
Поэтому в условиях может использоваться одно значение, например
if (value) {
// value is truthy
}
else {
// value is falsy
// it could be false, 0, '', null, undefined or NaN
}
Сравнение слабого равенства с ==
Неожиданные ситуации могут возникать при сравнении истинных и ложных значений с использованием ==
== |
true |
false |
0 |
'' |
null |
undefined |
NaN |
Infinity |
[] |
{} |
---|---|---|---|---|---|---|---|---|---|---|
true |
правда | ложный | ложный | ложный | ложный | ложный | ложный | ложный | ложный | ложный |
false |
ложный | правда | правда | правда | ложный | ложный | ложный | ложный | правда | ложный |
0 |
ложный | правда | правда | правда | ложный | ложный | ложный | ложный | правда | ложный |
'' |
ложный | правда | правда | правда | ложный | ложный | ложный | ложный | правда | ложный |
null |
ложный | ложный | ложный | ложный | правда | правда | ложный | ложный | ложный | ложный |
undefined |
ложный | ложный | ложный | ложный | правда | правда | ложный | ложный | ложный | ложный |
NaN |
ложный | ложный | ложный | ложный | ложный | ложный | ложный | ложный | ложный | ложный |
Infinity |
ложный | ложный | ложный | ложный | ложный | ложный | ложный | правда | ложный | ложный |
[] |
ложный | правда | правда | правда | ложный | ложный | ложный | ложный | ложный | ложный |
{} |
ложный | ложный | ложный | ложный | ложный | ложный | ложный | ложный | ложный | ложный |
Правила:
-
false
-
null
undefined
-
NaN
включая еще одинNaN
-
Infinity
но ее нельзя сравнивать сtrue
false
- Пустой массив — это правда, но сравнение с
true
false
false
true
Примеры:
// all true
false == 0;
0 == '';
null == undefined;
[] == false;
!![0] == true;
// all false
false == null;
NaN == NaN;
Infinity == true;
[] == true;
[0] == true;
Строгое сравнение с ===
Ситуация проясняется при использовании строгого сравнения, потому что типы значений должны совпадать:
=== |
true |
false |
0 |
'' |
null |
undefined |
NaN |
Infinity |
[] |
{} |
---|---|---|---|---|---|---|---|---|---|---|
true |
правда | ложный | ложный | ложный | ложный | ложный | ложный | ложный | ложный | ложный |
false |
ложный | правда | ложный | ложный | ложный | ложный | ложный | ложный | ложный | ложный |
0 |
ложный | ложный | правда | ложный | ложный | ложный | ложный | ложный | ложный | ложный |
'' |
ложный | ложный | ложный | правда | ложный | ложный | ложный | ложный | ложный | ложный |
null |
ложный | ложный | ложный | ложный | правда | ложный | ложный | ложный | ложный | ложный |
undefined |
ложный | ложный | ложный | ложный | ложный | правда | ложный | ложный | ложный | ложный |
NaN |
ложный | ложный | ложный | ложный | ложный | ложный | ложный | ложный | ложный | ложный |
Infinity |
ложный | ложный | ложный | ложный | ложный | ложный | ложный | правда | ложный | ложный |
[] |
ложный | ложный | ложный | ложный | ложный | ложный | ложный | ложный | ложный | ложный |
{} |
ложный | ложный | ложный | ложный | ложный | ложный | ложный | ложный | ложный | ложный |
Единственным исключением является NaN
рекомендации
Истинные и ложные ценности могут поймать самых опытных разработчиков. У новичков в программировании или миграции с других языков нет шансов! К счастью, есть простые шаги для выявления наиболее трудных для обнаружения ошибок при обработке истинных и ложных переменных:
1. Избегайте прямых сравнений
Редко необходимо сравнивать два истинных и ложных значения, когда одно значение всегда будет равно true или false:
// instead of
if (x == false) // ...
// runs if x is false, 0, '', or []
// use
if (!x) // ...
// runs if x is false, 0, '', NaN, null or undefined
2. Используйте ===
Используйте ===
!==
// instead of
if (x == y) // ...
// runs if x and y are both truthy or both falsy
// e.g. x = null and y = undefined
// use
if (x === y) // ...
// runs if x and y are identical...
// except when both are NaN
3. Конвертировать в реальные логические значения, где это необходимо
Любое значение может быть преобразовано в реальное логическое значение с использованием двойного отрицания !!
чтобы быть абсолютно уверенным, ложь генерируется только false
0
""
null
undefined
NaN
// instead of
if (x === y) // ...
// runs if x and y are identical...
// except when both are NaN
// use
if (!!x === !!y) // ...
// runs if x and y are identical...
// including when either or both are NaN
Вывод
Значения истина и ложь позволяют вам писать краткие условия JavaScript и троичные операторы. Однако всегда учитывайте крайние случаи. Мошеннический пустой массив или переменная NaN может привести к многим часам отладки горя!