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

Каков наиболее подходящий способ проверить, есть ли переменная undefined в JavaScript? Я видел несколько возможных способов:

if (window.myVariable)

или

if (typeof(myVariable) != "undefined")

или

if (myVariable) //This throws an error if undefined. Should this be in Try/Catch?

Ответ 1

Если вам интересно узнать, была ли указана переменная независимо от ее значения, то использование оператора in является самым безопасным способом. Рассмотрим этот пример.

// global scope
var theFu; // theFu has been declared, but its value is undefined
typeof theFu; // "undefined"

Но это не может быть предполагаемым результатом для некоторых случаев, поскольку переменная или свойство были объявлены, но просто не инициализированы. Используйте оператор in для более надежной проверки.

"theFu" in window; // true
"theFoo" in window; // false

Если вам интересно узнать, не была ли указана переменная или имеет значение undefined, используйте оператор typeof.

if (typeof myVar !== 'undefined')

Оператору typeof гарантируется возврат строки. Прямые сравнения с undefined являются неудобными, поскольку undefined могут быть перезаписаны.

window.undefined = "omg";
"omg" == undefined // true

Как отмечала @CMS, это было исправлено в ECMAScript 5th ed., А undefined не записывается.

if (window.myVar) также будет включать эти значения фальши, поэтому он не очень устойчив:

false
0
""
NaN
null
undefined

Благодаря @CMS за то, что ваш третий случай - if (myVariable) также может if (myVariable) ошибку в двух случаях. Во-первых, когда переменная не определена, которая вызывает ReferenceError.

// abc was never declared.
if (abc) {
    // ReferenceError: abc is not defined
} 

Другой случай - когда переменная определена, но имеет функцию геттера, которая вызывает ошибку при вызове. Например,

// or it a property that can throw an error
Object.defineProperty(window, "myVariable", { 
    get: function() { throw new Error("W00t?"); }, 
    set: undefined 
});
if (myVariable) {
    // Error: W00t?
}

Ответ 2

Я лично использую

myVar === undefined

Внимание: обратите внимание, что === используется над == и что myVar ранее объявлен (не определен).


Мне не нравится typeof myVar === "undefined". Я думаю, что он длинный и ненужный. (Я могу сделать то же самое в меньшем коде.)

Теперь некоторые люди будут кипеть от боли, когда они прочтут это, крича: "Подождите! WAAITTT!!! undefined можно переопределить!"

Круто. Я знаю это. Опять же, большинство переменных в Javascript можно переопределить. Если вы никогда не используете встроенный идентификатор, который можно переопределить?

Если вы будете следовать этому правилу, хорошо для вас: вы не лицемер.

Дело в том, что для того, чтобы делать много реальной работы в JS, разработчикам нужно полагаться на переопределяемые идентификаторы, чтобы быть тем, кем они являются. Я не слышу, как люди говорят мне, что я не должен использовать setTimeout, потому что кто-то может

window.setTimeout = function () {
    alert("Got you now!");
};

Нижняя строка, аргумент "он может быть переопределен", чтобы не использовать raw === undefined, является фиктивным.

(Если вы все еще боитесь переопределения undefined, почему вы слепо интегрируете непроверенный код библиотеки в свою базу кода? Или еще проще: инструмент для переливания.)


Кроме того, как и метод typeof, этот метод может "обнаруживать" необъявленные переменные:

if (window.someVar === undefined) {
    doSomething();
}

Но обе эти технологии просачиваются в их абстракции. Я призываю вас не использовать это или даже

if (typeof myVar !== "undefined") {
    doSomething();
}

Рассмотрим:

var iAmUndefined;

Чтобы узнать, объявлена ​​ли эта переменная или нет, вам может потребоваться обратиться к оператору in. (Во многих случаях вы можете просто прочитать код O_o).

if ("myVar" in window) {
    doSomething();
}

Но подождите! Там еще! Что, если какая-то прототипная магическая цепочка происходит...? Теперь даже верхнего оператора in недостаточно. (Хорошо, я закончил здесь эту часть, кроме как сказать, что в 99% случаев === undefined (и **** cough **** typeof) работает отлично. Если вам действительно все равно, вы может прочитать об этом предмете самостоятельно.)

Ответ 3

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

if (typeof someUndeclaredVariable == "undefined") {
    // Works
}

if (someUndeclaredVariable === undefined) { 
    // Throws an error
}

Ответ 4

Вам нужно использовать typeof.

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

Ответ 5

Обновление 2018-07-25

Прошло почти пять лет с тех пор, как этот пост был впервые создан, и JavaScript прошел большой путь. Повторяя тесты в оригинальном посте, я не обнаружил последовательных различий между следующими методами тестирования:

  • abc === undefined
  • abc === void 0
  • typeof abc == 'undefined'
  • typeof abc === 'undefined'

Даже когда я модифицировал тесты, чтобы Chrome не оптимизировал их, различия были незначительными. Поэтому я бы порекомендовал abc === undefined для ясности.

Соответствующий контент из chrome://version:

  • Google Chrome: 67.0.3396.99 (официальная сборка) (64-разрядная версия) (когорта: стабильная)
  • Редакция: a337fbf3c2ab8ebc6b64b0bfdce73a20e2e2252b-refs/branch-Heads/3396 @{# 790}
  • ОС: Windows
  • JavaScript: V8 6.7.288.46
  • Пользовательский агент: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, как Gecko) Chrome/67.0.3396.99 Safari/537.36

Оригинальный пост 2013-11-01

В Google Chrome следующее было немного быстрее, чем тест typeof:

if (abc === void 0) {
    // Undefined
}

Разница была незначительной. Тем не менее, этот код является более кратким и понятным для тех, кто знает, что означает 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;

Результаты были следующими:

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

Ответ 6

Если это undefined, он не будет равен строке, содержащей символы "undefined", поскольку строка не undefined.

Вы можете проверить тип переменной:

if (typeof(something) != "undefined") ...

Иногда вам даже не нужно проверять тип. Если значение переменной не может быть оценено в false, когда оно установлено (например, если это функция), вы можете просто оценить переменную. Пример:

if (something) {
  something(param);
}

Ответ 7

Некоторые сценарии, иллюстрирующие результаты различных ответов: http://jsfiddle.net/drzaus/UVjM4/

(Обратите внимание, что использование тегов var для in имеет значение, когда в обертованной области)

Код для справки:

(function(undefined) {
    var definedButNotInitialized;
    definedAndInitialized = 3;
    someObject = {
        firstProp: "1"
        , secondProp: false
        // , undefinedProp not defined
    }
    // var notDefined;

    var tests = [
        'definedButNotInitialized in window',
        'definedAndInitialized in window',
        'someObject.firstProp in window',
        'someObject.secondProp in window',
        'someObject.undefinedProp in window',
        'notDefined in window',

        '"definedButNotInitialized" in window',
        '"definedAndInitialized" in window',
        '"someObject.firstProp" in window',
        '"someObject.secondProp" in window',
        '"someObject.undefinedProp" in window',
        '"notDefined" in window',

        'typeof definedButNotInitialized == "undefined"',
        'typeof definedButNotInitialized === typeof undefined',
        'definedButNotInitialized === undefined',
        '! definedButNotInitialized',
        '!! definedButNotInitialized',

        'typeof definedAndInitialized == "undefined"',
        'typeof definedAndInitialized === typeof undefined',
        'definedAndInitialized === undefined',
        '! definedAndInitialized',
        '!! definedAndInitialized',

        'typeof someObject.firstProp == "undefined"',
        'typeof someObject.firstProp === typeof undefined',
        'someObject.firstProp === undefined',
        '! someObject.firstProp',
        '!! someObject.firstProp',

        'typeof someObject.secondProp == "undefined"',
        'typeof someObject.secondProp === typeof undefined',
        'someObject.secondProp === undefined',
        '! someObject.secondProp',
        '!! someObject.secondProp',

        'typeof someObject.undefinedProp == "undefined"',
        'typeof someObject.undefinedProp === typeof undefined',
        'someObject.undefinedProp === undefined',
        '! someObject.undefinedProp',
        '!! someObject.undefinedProp',

        'typeof notDefined == "undefined"',
        'typeof notDefined === typeof undefined',
        'notDefined === undefined',
        '! notDefined',
        '!! notDefined'
    ];

    var output = document.getElementById('results');
    var result = '';
    for(var t in tests) {
        if( !tests.hasOwnProperty(t) ) continue; // bleh

        try {
            result = eval(tests[t]);
        } catch(ex) {
            result = 'Exception--' + ex;
        }
        console.log(tests[t], result);
        output.innerHTML += "\n" + tests[t] + ": " + result;
    }
})();

И результаты:

definedButNotInitialized in window: true
definedAndInitialized in window: false
someObject.firstProp in window: false
someObject.secondProp in window: false
someObject.undefinedProp in window: true
notDefined in window: Exception--ReferenceError: notDefined is not defined
"definedButNotInitialized" in window: false
"definedAndInitialized" in window: true
"someObject.firstProp" in window: false
"someObject.secondProp" in window: false
"someObject.undefinedProp" in window: false
"notDefined" in window: false
typeof definedButNotInitialized == "undefined": true
typeof definedButNotInitialized === typeof undefined: true
definedButNotInitialized === undefined: true
! definedButNotInitialized: true
!! definedButNotInitialized: false
typeof definedAndInitialized == "undefined": false
typeof definedAndInitialized === typeof undefined: false
definedAndInitialized === undefined: false
! definedAndInitialized: false
!! definedAndInitialized: true
typeof someObject.firstProp == "undefined": false
typeof someObject.firstProp === typeof undefined: false
someObject.firstProp === undefined: false
! someObject.firstProp: false
!! someObject.firstProp: true
typeof someObject.secondProp == "undefined": false
typeof someObject.secondProp === typeof undefined: false
someObject.secondProp === undefined: false
! someObject.secondProp: true
!! someObject.secondProp: false
typeof someObject.undefinedProp == "undefined": true
typeof someObject.undefinedProp === typeof undefined: true
someObject.undefinedProp === undefined: true
! someObject.undefinedProp: true
!! someObject.undefinedProp: false
typeof notDefined == "undefined": true
typeof notDefined === typeof undefined: true
notDefined === undefined: Exception--ReferenceError: notDefined is not defined
! notDefined: Exception--ReferenceError: notDefined is not defined
!! notDefined: Exception--ReferenceError: notDefined is not defined

Ответ 8

if (typeof foo == 'undefined') {
 // Do something
};

Обратите внимание, что в этом случае не требуется строгое сравнение (!==), так как typeof всегда будет возвращать строку.

Ответ 9

В в этой статье Я читал, что фреймворки, такие как Underscore.js используйте эту функцию:

function isUndefined(obj){
    return obj === void 0;
}

Ответ 10

Лично я всегда использую следующее:

var x;
if( x === undefined) {
    //Do something here
}
else {
   //Do something else here
}

Свойство window.undefined не доступно для записи во всех современных браузерах (JavaScript 1.8.5 или новее). Из документации Mozilla: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined, я вижу следующее: Одна из причин использования typeof() заключается в том, что она не выдает ошибку, если переменная имеет не определено.

Я предпочитаю использовать подход

x === undefined 

потому что он терпит неудачу и взрывается в моем лице, а не бесшумно проходит/терпит неудачу, если x не был объявлен ранее. Это предупреждает меня, что x не объявлен. Я считаю, что все переменные, используемые в JavaScript, должны быть объявлены.

Ответ 11

Самый надежный способ проверки undefined - использовать void 0.

Это совместимо с более старыми и более старыми браузерами и не может быть перезаписано, например, как window.undefined.

if( myVar === void 0){
    //yup it undefined
}

Ответ 12

Поскольку ни один из ответов не помог мне, я предлагаю сделать это. Это работало для меня в Internet Explorer 8:

if (typeof variable_name.value === 'undefined') {
    // variable_name is undefined
}

Ответ 13

Напротив ответа @Thomas Eding:

Если я забыл объявить myVar в своем коде, тогда я получу myVar is not defined.

Возьмем реальный пример:

У меня есть имя переменной, но я не уверен, что она объявлена ​​где-то или нет.

Затем ответ @Anurag поможет:

var myVariableToCheck = 'myVar';
if (window[myVariableToCheck] === undefined)
    console.log("Not declared or declared, but undefined.");

// Or you can check it directly 
if (window['myVar'] === undefined) 
    console.log("Not declared or declared, but undefined.");

Ответ 14

// x has not been defined before
if (typeof x === 'undefined') { // Evaluates to true without errors.
   // These statements execute.
}

if (x === undefined) { // Throws a ReferenceError

}

Ответ 15

    var x;
    if (x === undefined) {
        alert ("I am declared, but not defined.")
    };
    if (typeof y === "undefined") {
        alert ("I am not even declared.")
    };

    /* One more thing to understand: typeof ==='undefined' also checks 
       for if a variable is declared, but no value is assigned. In other 
       words, the variable is declared, but not defined. */

    // Will repeat above logic of x for typeof === 'undefined'
    if (x === undefined) {
        alert ("I am declared, but not defined.")
    };
    /* So typeof === 'undefined' works for both, but x === undefined 
       only works for a variable which is at least declared. */

    /* Say if I try using typeof === undefined (not in quotes) for 
       a variable which is not even declared, we will get run a 
       time error. */

    if (z === undefined) {
        alert ("I am neither declared nor defined.")
    };
    // I got this error for z ReferenceError: z is not defined 

Ответ 16

Я использую его как параметр функции и исключаю его при выполнении функции таким образом, что получаю "реальный" undefined. Хотя это требует, чтобы вы включили код внутри функции. Я нашел это при чтении источника jQuery.

undefined = 2;

(function (undefined) {
   console.log(undefined); // prints out undefined
   // and for comparison:
   if (undeclaredvar === undefined) console.log("it works!")
})()

Конечно, вы могли бы просто использовать typeof. Но весь мой код обычно находится внутри содержащейся функции, поэтому использование этого метода, вероятно, сэкономит мне несколько байтов здесь и там.