Как проверить "undefined" в JavaScript?
Заголовок: Как правильно проверить, является ли переменная неопределенной в JavaScript?
Я столкнулся с проблемой определения, является ли переменная в JavaScript неопределенной (undefined). Недавно я наткнулся на несколько способов, которыми, казалось бы, можно это сделать, и теперь не уверен, какой подход является наиболее корректным.
Вот некоторые из способов, которые я рассмотрел:
Использование условия:
if (window.myVariable)
С помощью оператора typeof:
if (typeof(myVariable) != "undefined")
Простой проверкой переменной:
if (myVariable) // Это вызывает ошибку, если переменная неопределена. Нужно ли оборачивать это в блок try/catch?
Существуют ли какие-либо лучшие практики или рекомендации по этому вопросу? Какой метод является наиболее безопасным и надежным для проверки неопределенных переменных? Спасибо!
4 ответ(ов)
Если вас интересует, была ли переменная объявлена, независимо от её значения, то самым безопасным способом является использование оператора in
. Рассмотрим следующий пример:
// глобальная область видимости
var theFu; // theFu была объявлена, но её значение — undefined
typeof theFu; // "undefined"
Однако в некоторых случаях это может не дать ожидаемого результата, поскольку переменная или свойство были объявлены, но не инициализированы. Используйте оператор in
для более надежной проверки.
"theFu" in window; // true
"theFoo" in window; // false
Если вы хотите выяснить, была ли переменная не объявлена или имеет значение undefined
, то используйте оператор typeof
, который гарантирует возврат строки:
if (typeof myVar !== 'undefined')
Прямые сравнения с undefined
могут быть проблематичными, так как undefined
может быть переопределено.
window.undefined = "foo";
"foo" == undefined // true
Как указал @CMS, это было исправлено в 5-й редакции ECMAScript, и теперь undefined
является неизменяемым.
Обратите внимание, что if (window.myVar)
также будет включать ложные значения, поэтому этот метод не очень надежен:
false
0
""
NaN
null
undefined
Благодаря @CMS стоит отметить, что ваш третий случай — if (myVariable)
может вызвать ошибку в двух случаях. Первый — когда переменная не была определена, что приводит к ReferenceError
.
// abc никогда не был объявлен.
if (abc) {
// ReferenceError: abc is not defined
}
Второй случай — когда переменная была определена, но является свойством с функцией доступа, которая вызывает ошибку при вызове. Например:
// или это свойство, которое может вызвать ошибку
Object.defineProperty(window, "myVariable", {
get: function() { throw new Error("W00t?"); },
set: undefined
});
if (myVariable) {
// Error: W00t?
}
Надеюсь, это поможет!
Обновление 2020
Одна из причин, по которой я предпочитал проверку с помощью typeof
(а именно, что undefined
может быть переопределен), стала неактуальной с массовым внедрением ECMAScript 5. Другая причина заключается в том, что вы можете использовать typeof
для проверки типа необъявленной переменной, хотя это всегда было маловостребовано. Поэтому теперь я бы рекомендовал использовать прямое сравнение в большинстве ситуаций:
myVariable === undefined
Оригинальный ответ от 2010 года
Я предпочитаю использовать typeof
. Это будет работать, даже если переменная никогда не была объявлена, в отличие от любых сравнений с операторами ==
или ===
, а также приведения типов с помощью if
. (undefined
, в отличие от null
, может также быть переопределен в средах ECMAScript 3, что делает его ненадежным для сравнения, хотя почти все распространенные среды теперь соответствуют ECMAScript 5 или выше).
if (typeof someUndeclaredVariable == "undefined") {
// Работает
}
if (someUndeclaredVariable === undefined) {
// Вызывает ошибку
}
Вы можете использовать typeof
, вот так:
if (typeof something !== "undefined") {
// ...
}
Это позволяет безопасно проверять, определена ли переменная something
, прежде чем использовать её в коде.
Обновление 25.07.2018
Прошло почти пять лет с момента публикации этого поста, и JavaScript существенно изменился. Повторяя тесты из оригинальной статьи, я не нашел значительных различий между следующими методами проверки:
abc === undefined
abc === void 0
typeof abc == 'undefined'
typeof abc === 'undefined'
Даже когда я модифицировал тесты, чтобы предотвратить их оптимизацию в Chrome, различия оказались незначительными. Поэтому теперь я рекомендую использовать abc === undefined
для большей ясности.
Актуальная информация из chrome://version
:
- Google Chrome: 67.0.3396.99 (Официальная сборка) (64-битная) (коорта: Stable)
- Ревизия: a337fbf3c2ab8ebc6b64b0bfdce73a20e2e2252b-refs/branch-heads/3396@
- Операционная система: Windows
- JavaScript: V8 6.7.288.46
- User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, как Gecko) Chrome/67.0.3396.99 Safari/537.36
Оригинальный пост 01.11.2013
В Google Chrome следующий способ был чуть быстрее, чем тест с typeof
:
if (abc === void 0) {
// Неопределено
}
Разница была несущественной. Однако этот код более лаконичен и понятен на первый взгляд для тех, кто знает, что значит void 0
. Обратите внимание, что abc
по-прежнему должен быть объявлен.
Оба способа — typeof
и void
— были значительно быстрее, чем прямое сравнение с undefined
. Я использовал следующий формат теста в консоли разработчика Chrome:
var abc;
start = +new Date();
for (var i = 0; i < 10000000; i++) {
if (TEST) {
void 1;
}
}
end = +new Date();
end - start;
Результаты были следующими:
Тест: | abc === undefined abc === void 0 typeof abc == 'undefined'
------+---------------------------------------------------------------------
x10M | 13678 ms 9854 ms 9888 ms
x1 | 1367.8 ns 985.4 ns 988.8 ns
Обратите внимание, что первая строка в миллисекундах, а вторая строка — в наносекундах. Разница в 3.4 наносекунды ничтожна. Времена были довольно стабильны в последующих тестах.
Существует ли стандартная функция для проверки переменных на null, undefined или пустые значения в JavaScript?
Как определить, является ли переменная 'undefined' или 'null'?
Проверка существования переменной в JavaScript (определена/инициализирована)
Как проверить неопределённую переменную в JavaScript
Почему null является объектом и в чем разница между null и undefined?