Как проверить "undefined" в JavaScript? [дубликат]

этот вопрос уже есть ответ здесь:

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

if (window.myVariable)

или

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

или

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

16 ответов


Если вам интересно узнать, была ли объявлена переменная независимо от ее значения, используйте 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) также может выдать ошибку в двух случаях. Во-первых, когда переменная не была определена, которая выдает ReferenceError.

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

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

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

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

myVar === undefined

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


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

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 оператора. (Во многих случаях, вы можете просто прочитать код О_о).

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

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


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

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

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

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

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

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

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

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

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

if (something) {
  something(param);
}

некоторые сценарии, иллюстрирующие результаты различных ответов: 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

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

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


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

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

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

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

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

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

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

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

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

x === undefined 

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


обновление 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 следующее Было немного быстрее, чем


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

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

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

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

}

напротив @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.");

    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 

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

undefined = 2;

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

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