Ложные значения в JavaScript
У меня сегодня был интересный вопрос для интервью, который немного озадачил меня. Меня спросили о фальшивых ценностях. Так что undefined, NaN, null, 0 и пустая строка - все равно false. По какой причине это полезно знать в JavaScript? Единственное, о чем я могу думать, это вместо того, чтобы делать это:
if (mystring === '' || mystring === undefined) { }
Я могу сделать это:
if (!mystring)
Это единственное полезное приложение?
6 ответов
Одна опасная проблема ложных ценностей, о которой вы должны знать, - это проверка наличия определенного свойства.
Предположим, вы хотите проверить наличие нового свойства; когда это свойство действительно может иметь значение 0
или же ""
, вы не можете просто проверить его доступность, используя
if (!someObject.someProperty)
/* incorrectly assume that someProperty is unavailable */
В этом случае вы должны проверить, действительно ли он присутствует или нет:
if (typeof someObject.someProperty == "undefined")
/* now it's really not available */
Также имейте в виду, что NaN
не равняется ни на что, даже не на себя (NaN != NaN
).
Есть две отдельные проблемы со значениями 'falsey' в JavaScript.
Во-первых, существует официальная схема преобразования, которая возвращается Boolean(x). Это возвращает false, когда x равен false или 0 или NaN или null или undefined или "" и true в противном случае. Это то же поведение, что и
if (condition) {/*true path*/} else {/*false path*/}
то есть ложный путь выполняется, если Boolean (условие) возвратил бы ложь, и истинный путь выполняется в противном случае. Это поведение часто используется, чтобы проверить, определено ли свойство. Однако делать это небезопасно, если только вы не уверены, что свойство будет объектом или массивом, если оно определено. Самый безопасный способ проверить, определено ли свойство, это сделать
if (property != null) { /*property is defined*/}
который гарантирует, что свойство не является нулевым или неопределенным. Если вы хотите убедиться, что свойство не определено, сделайте
if (property !== undefined) { /*property is not undefined (but may be null)*/ }
(обратите внимание на дополнительные = в!==).
Во-вторых, есть все значения, которые == ложные. Это все, что может быть приведено к 0 (то есть то, к чему приводит ложь). Это включает в себя все значения, которые преобразуются в ложь, кроме NaN (который не может == ложь в силу того, что он никогда не == что-либо), ноль и неопределенный. Но он также включает все объекты, которые при преобразовании в строку и затем в число равны 0. Например, это включает в себя все, что при преобразовании в строку является либо пустой строкой "", либо "0", либо "-0". "или" +0 "или" 0x00 ", или" 000 ", или" 0e0 ", или" 0.0000 ".... например,
({toString: function() {return "-00.0e000";}}) == false
правда. Интересно, что это включает в себя пустой массив и любое вложение массивов, содержащих только один другой элемент, который возвращает пустую строку или строку 0, так как массивы, представленные в виде строк, показывают только содержимое без окружающих скобок. То есть,
[[[[0]]]] == false; // Because [[[[0]]]].toString() === "0"
[] == false;
[[[""]]] == false;
["0"] == false;
[[({toString: function() {return "0";}})]] == false;
Полный алгоритм вычисления == false описан здесь.
Причина, по которой это важно, заключается в том, что это может привести к тонким, трудным для поиска ошибок, если вы не понимаете большинство из этих правил. Наиболее важные выносы, вероятно, как if (condition)
работает и что использование === позволяет избежать большинства других сумасшедших вещей.
Важно понимать, как это работает в JS, поэтому вы не удивитесь. Не обязательно только то, что ложно, но что является правдой и как они сравниваются друг с другом.
Одним из примеров является то, что "0" считается равным 0 с ==, но это не равно "" - хотя 0 это. Сравнение JavaScript не всегда транзитивно.
Так что это означает, что только потому, что (foo==bar && bar==fizz)
правда, (foo==fizz)
это не всегда так. Чтобы перейти к приведенному выше примеру, '0' == 0 и 0 == '', но '0'!='' - потому что вы сравниваете строки в последнем случае, поэтому они сравниваются как строки и не приводятся на номера.
Важно знать, что 0
оценивает false
чтобы не делать такие вещи, как:
if(str.indexOf('foo'))
Они также полезны для установки значений по умолчанию...
function foo(bar){
alert(bar || "default");
}
Я знаю, что многие люди пытаются сделать
if (typeof(foo) === "undefined"){}
чтобы обойти ложь, но у этого есть свои проблемы, потому что
typeof(null) === "object"
по какой-то причине
Полезно определить, есть ли в браузере определенные предопределенные объекты:
if(!!navigator.geolocation){
// executes if the browser has geolocation support
}
if(!!document.createElement('canvas').getContext){
// executes if the browser supports <canvas>
}
Объяснение: navigator.geolocation является объектом или не определен. В случае, если это объект !navigator.geolocation
вернет false, если он не определен, он вернет true. Таким образом, чтобы проверить, включена ли в браузере геолокация, вы хотите "перевернуть" логическое значение еще раз, добавив еще один !
,