30

Как проверить "undefined" в JavaScript?

19

Заголовок: Как правильно проверить, является ли переменная неопределенной в JavaScript?

Я столкнулся с проблемой определения, является ли переменная в JavaScript неопределенной (undefined). Недавно я наткнулся на несколько способов, которыми, казалось бы, можно это сделать, и теперь не уверен, какой подход является наиболее корректным.

Вот некоторые из способов, которые я рассмотрел:

  1. Использование условия:

    if (window.myVariable)
    
  2. С помощью оператора typeof:

    if (typeof(myVariable) != "undefined")
    
  3. Простой проверкой переменной:

    if (myVariable) // Это вызывает ошибку, если переменная неопределена. Нужно ли оборачивать это в блок try/catch?
    

Существуют ли какие-либо лучшие практики или рекомендации по этому вопросу? Какой метод является наиболее безопасным и надежным для проверки неопределенных переменных? Спасибо!

4 ответ(ов)

32

Если вас интересует, была ли переменная объявлена, независимо от её значения, то самым безопасным способом является использование оператора 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?
}

Надеюсь, это поможет!

3

Обновление 2020

Одна из причин, по которой я предпочитал проверку с помощью typeof (а именно, что undefined может быть переопределен), стала неактуальной с массовым внедрением ECMAScript 5. Другая причина заключается в том, что вы можете использовать typeof для проверки типа необъявленной переменной, хотя это всегда было маловостребовано. Поэтому теперь я бы рекомендовал использовать прямое сравнение в большинстве ситуаций:

myVariable === undefined

Оригинальный ответ от 2010 года

Я предпочитаю использовать typeof. Это будет работать, даже если переменная никогда не была объявлена, в отличие от любых сравнений с операторами == или ===, а также приведения типов с помощью if. (undefined, в отличие от null, может также быть переопределен в средах ECMAScript 3, что делает его ненадежным для сравнения, хотя почти все распространенные среды теперь соответствуют ECMAScript 5 или выше).

if (typeof someUndeclaredVariable == "undefined") {
    // Работает
}

if (someUndeclaredVariable === undefined) { 
    // Вызывает ошибку
}
1

Вы можете использовать typeof, вот так:

if (typeof something !== "undefined") {
    // ...
}

Это позволяет безопасно проверять, определена ли переменная something, прежде чем использовать её в коде.

0

Обновление 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 наносекунды ничтожна. Времена были довольно стабильны в последующих тестах.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь