Вопрос: Как проверить «неопределенный» в JavaScript? [Дубликат]


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

if (window.myVariable)

Или

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

Или

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

1842


источник


Ответы:


Если вам интересно узнать, была ли объявлена ​​переменная независимо от ее значения, используйте 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 5th, и undefinedне записывается.

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

ложный
0
«»
NaN
ноль
не определено 

Благодаря @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?
}

2114



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

myVar === undefined

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


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

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

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

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

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

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

Итог, аргумент «можно переопределить», чтобы не использовать необработанный === 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(и **** кашель **** typeof) работает отлично. Если вам действительно все равно, вы можете прочитать об этом предмете самостоятельно.)


867



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

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

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

147



Вы должны использовать typeof,

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

49



If it is undefined, it will not be equal to a string that contains the characters "undefined", as the string is not undefined.

You can check the type of the variable:

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

Sometimes you don't even have to check the type. If the value of the variable can't evaluate to false when it's set (for example if it's a function), then you can just evalue the variable. Example:

if (something) {
  something(param);
}

20



Some scenarios illustrating the results of the various answers: http://jsfiddle.net/drzaus/UVjM4/

(Note that the use of var for in tests make a difference when in a scoped wrapper)

Code for reference:

(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;
    }
})();

And results:

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

16



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

Note that strict comparison (!==) is not necessary in this case, since typeof will always return a string.


15



In this article I read that frameworks like Underscore.js use this function:

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

15



The most reliable way I know of checking for undefined is to use void 0.

This is compatible with newer and older browsers, alike, and cannot be overwritten like window.undefined can in some cases.

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

9