ChatGPT解决这个技术问题 Extra ChatGPT

How can I check for "undefined" in JavaScript? [duplicate]

This question already has answers here: Detecting an undefined object property (50 answers) How to check a not-defined variable in JavaScript (15 answers) How to handle 'undefined' in JavaScript [duplicate] (3 answers) How can I check if a variable exist in JavaScript? (8 answers) Closed 7 years ago.

What is the most appropriate way to test if a variable is undefined in JavaScript?

I've seen several possible ways:

if (window.myVariable)

Or

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

Or

if (myVariable) // This throws an error if undefined. Should this be in Try/Catch?
Do you want to check for only undefined, or null as well?
@Robert - that question has an accepted answer that answers here have proven to be wrong
That "duplicate" is about object properties, so some of the answers don't apply very well to this question, asking about variables.

r
reformed

If you are interested in finding out whether a variable has been declared regardless of its value, then using the in operator is the safest way to go. Consider this example:

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

But this may not be the intended result for some cases, since the variable or property was declared but just not initialized. Use the in operator for a more robust check.

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

If you are interested in knowing whether the variable hasn't been declared or has the value undefined, then use the typeof operator, which is guaranteed to return a string:

if (typeof myVar !== 'undefined')

Direct comparisons against undefined are troublesome as undefined can be overwritten.

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

As @CMS pointed out, this has been patched in ECMAScript 5th ed., and undefined is non-writable.

if (window.myVar) will also include these falsy values, so it's not very robust:

false
0
""
NaN
null
undefined

Thanks to @CMS for pointing out that your third case - if (myVariable) can also throw an error in two cases. The first is when the variable hasn't been defined which throws a ReferenceError.

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

The other case is when the variable has been defined, but has a getter function which throws an error when invoked. For example,

// 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?
}

@Anurag, the third case will throw a ReferenceError if myVariable is not declared...
@Anurag, you're welcome, since you talk about ES5, maybe is worth mentioning that undefined is now described as non-writable, non-configurable and non-enumerable. So, window.undefined = "omg"; will simply fail silently or throw under strict mode.
Can "typeof" be redefined?
typeof is a language statement, it cannot be redefined any more than if/else/while/for/function etc. could be.
undefined is immutable in modern browsers. Setting window.undefined does nothing.
T
Thomas Eding

I personally use

myVar === undefined

Warning: Please note that === is used over == and that myVar has been previously declared (not defined).

I do not like typeof myVar === "undefined". I think it is long winded and unnecessary. (I can get the same done in less code.)

Now some people will keel over in pain when they read this, screaming: "Wait! WAAITTT!!! undefined can be redefined!"

Cool. I know this. Then again, most variables in Javascript can be redefined. Should you never use any built-in identifier that can be redefined?

If you follow this rule, good for you: you aren't a hypocrite.

The thing is, in order to do lots of real work in JS, developers need to rely on redefinable identifiers to be what they are. I don't hear people telling me that I shouldn't use setTimeout because someone can

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

Bottom line, the "it can be redefined" argument to not use a raw === undefined is bogus.

(If you are still scared of undefined being redefined, why are you blindly integrating untested library code into your code base? Or even simpler: a linting tool.)

Also, like the typeof approach, this technique can "detect" undeclared variables:

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

But both these techniques leak in their abstraction. I urge you not to use this or even

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

Consider:

var iAmUndefined;

To catch whether or not that variable is declared or not, you may need to resort to the in operator. (In many cases, you can simply read the code O_o).

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

But wait! There's more! What if some prototype chain magic is happening…? Now even the superior in operator does not suffice. (Okay, I'm done here about this part except to say that for 99% of the time, === undefined (and ****cough**** typeof) works just fine. If you really care, you can read about this subject on its own.)


It's marginally more likely that undefined could be redefined, just because people do use it for such checks. Some people habitually put the constant on the left-hand side when doing such checks: if (undefined == someVariable). It only takes a typo for this to silently redefine undefined: if (undefined = someVariable).
I never write code that has undefined on the LHS. Even if I did, the fact that I use === instead of == makes the typo extremely unlikely. But the fact that == is incorrect is more of a worry. In any case, a bug like that is usually easy to find. Kind of like this bug: typeof x == "undefned".
How could this be upvoted 41 times, it simply doesn't work. If myVar is indeed undefined the code will throw an error, and it's easy to test - jsfiddle.net/WcM5g The proper way is typeof myVar === 'undefined'.
@Laurent: A joke right? This assumes the variable was declared in some way or the other, such as by a var keyword or a function parameter. I would sell my soul before I (intentionally) wrote code that tried acting on undeclared variables in any which way. Remember, undeclared and undefined are two different concepts in JS.
@Andy In C (and C++), it is both common and good practice to reverse operands like that, to avoid typos. if (NULL = myVar) fails to compile and is instantly caught, whereas if (myVar = NULL) creates a bug that may be difficult to track down depending on what other code is around it. Modern compilers should give you a warning, but many experienced C programmers have already developed the habit of swapping the order.
T
Tim Down

2020 Update

One of my reasons for preferring a typeof check (namely, that undefined can be redefined) became irrelevant with the mass adoption of ECMAScript 5. The other, that you can use typeof to check the type of an undeclared variable, was always niche. Therefore, I'd now recommend using a direct comparison in most situations:

myVariable === undefined

Original answer from 2010

Using typeof is my preference. It will work when the variable has never been declared, unlike any comparison with the == or === operators or type coercion using if. (undefined, unlike null, may also be redefined in ECMAScript 3 environments, making it unreliable for comparison, although nearly all common environments now are compliant with ECMAScript 5 or above).

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

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

You might want to check if a particular global variable representing a piece of functionality has already been defined. For example, library code may wish to check that the library has not already previously been included.
'xyz' in window or 'xyz' in self are much better
@JamiePate: Just to be clear, I disagree that 'xyz' in window is a better answer than typeof xyz == "undefined" because it is testing the wrong thing. The in operator checks for the existence of a property, regardless of its value, while the question at least appears to be asking how to test if the value of a variable is undefined. Perhaps a better example for me to choose would have been var foo; "foo" in window; this returns true while foo is definitely undefined.
@JamiePate: Why is xyz === undefined better than typeof xyz == "undefined"? Agreed about globals, but of the two of us only you have been recommending checking properties of window.
It's redundant in most cases (and less readable). If you know xyz is a declared variable, why go through the extra trouble? Type checking and string comparison are much slower in some browsers, so if you do it a lot in a tight loop you will lose some performance. jsperf.com/type-of-undefined-vs-undefined/6
J
Jacob Relkin

You can use typeof, like this:

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

Or just something !== undefined, assuming you've already done var undefined, pre-cautiously.
Good to see you added the quotes now. However, as mentioned in my answer, note that strict comparison (!==) is not necessary in this case, since typeof will always return a string.
Mathias: using strict or non-strict comparison here is a matter of personal taste. Both will always work, and neither is more correct. It could depend on whether your default position is to always use strict comparison unless specifically requiring type coercion (as recommended by Crockford, for example) or whether you prefer to use non-strict comparison except when strictness is required.
This is inaccurate. You absolutely don't need to use typeof.
Oh, now I got what you mean; your comment is misleading because was looking like related to the correctness of the code. Yes, one doesn't need to use it, since everything is matter of tastes; if you know what you are doing you don't even need to sanitize user inputs; that doesn't mean that it shouldn't be done. In this case, among all the answers, using typeof is the safest and less error prone option. More than writing such confusing comment I would have edited the answer to use another term instead of need. Like "You can|should|better|might use typeof" for example :)
K
Kamafeather

Update 2018-07-25

It's been nearly five years since this post was first made, and JavaScript has come a long way. In repeating the tests in the original post, I found no consistent difference between the following test methods:

abc === undefined

abc === void 0

typeof abc == 'undefined'

typeof abc === 'undefined'

Even when I modified the tests to prevent Chrome from optimizing them away, the differences were insignificant. As such, I'd now recommend abc === undefined for clarity.

Relevant content from chrome://version:

Google Chrome: 67.0.3396.99 (Official Build) (64-bit) (cohort: Stable)

Revision: a337fbf3c2ab8ebc6b64b0bfdce73a20e2e2252b-refs/branch-heads/3396@{#790}

OS: Windows

JavaScript: V8 6.7.288.46

User Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36

Original post 2013-11-01

In Google Chrome, the following was ever so slightly faster than a typeof test:

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

The difference was negligible. However, this code is more concise, and clearer at a glance to someone who knows what void 0 means. Note, however, that abc must still be declared.

Both typeof and void were significantly faster than comparing directly against undefined. I used the following test format in the Chrome developer console:

var abc;
start = +new Date();
for (var i = 0; i < 10000000; i++) {
    if (TEST) {
        void 1;
    }
}
end = +new Date();
end - start;

The results were as follows:

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

Note that the first row is in milliseconds, while the second row is in nanoseconds. A difference of 3.4 nanoseconds is nothing. The times were pretty consistent in subsequent tests.


Aww, so heartbreaking that this is -1; I spent a good amount of time testing this. Oh well. It's good info, so I'll leave it here. Remember, don't use === to test for undefined!
i assume the -1 was because of 1) <q>and clearer at a glance to someone who knows what void 0 means</q>, since void 0 sounds more unusual to me, 2) you should share your perf tests instead, but mainly 3) your first example (abc === void 0) throws an exception if abc is undefined.
added your method to my test list and it does check out (not that I doubted you) -- jsfiddle.net/drzaus/UVjM4/8
I think the best compromise between clarity and speed, given these numbers (which are from a while ago), is the typeof test.
I find it amazing that the undefined compare is slower than to void 0. I imagine that the running JS version is new enough for undefined to be guaranteed constant. So sad.
G
Guffa

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

No need for the parentheses: typeof is an operator, not a function.
@Tim - It can be used both ways.
Yes, I know that it works with the parentheses, which is because the parentheses here form the grouping operator that simply evaluates and returns the operand inside. I merely said that they were unnecessary.
M
Mathias Bynens
if (typeof foo == 'undefined') {
 // Do something
};

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


What's with the semi-colon (};)?
@J-P: The semicolon after the closing brace is just an empty statement.
@Gumbo, sorry, what I meant to ask was: "What purpose is the semi-colon serving?"
I've not encountered a minifier that can't handle if(){} without a ; ... Which minifiers are you referring to? You say that this is how you end every other statement... I guess that's true. But, a block statement {} is already a statement in and of its own. Adding a ; makes it two statements, technically. Syntactically, it's redundant. Even automatic semi-colon insertion won't add a semi-colon there...
@J-P: I guess I started doing it years ago after reading the Packer documentation. Packer expects semicolons after function() {} declarations. You’re right though — apparently it’s not required after if statements, but somehow I still think it makes sense.
d
drzaus

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

note the use of undefined within a scope wrapper; this not only protects against the (unusual) case of "oh but undefined can be redefined`" but also 'helps' with minification.
P
Peter Mortensen

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

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

H
Hrishi

Personally, I always use the following:

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

The window.undefined property is non-writable in all modern browsers (JavaScript 1.8.5 or later). From Mozilla's documentation: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/undefined, I see this: One reason to use typeof() is that it does not throw an error if the variable has not been defined.

I prefer to have the approach of using

x === undefined 

because it fails and blows up in my face rather than silently passing/failing if x has not been declared before. This alerts me that x is not declared. I believe all variables used in JavaScript should be declared.


you can redeclare undefined using scope wrappers: (function($, undefined){ /* undefined is 'abc' in here */ })(jQuery, 'abc');, which is why ppl complain that it's technically not safe unless you're 100% sure you know where your code is being run.
Great point about wanting undeclared variable to blow up - this does not happen with typeof.
With the July 2021 Chrome for Windows (Version 92.0.4515.107), I tried: if ( myVar === undefined ), if ( myVar === 'undefined' ), if ( myVar === void 0), or if ( !myVar ) All failed! Every case threw an undefined JavaScript error, and effectively returned a 'true' causing the branch to be taken... Solution: if ( !window.myVar ) myVar = false; That's all I needed, get it declared globally as false, if a previously library wasn't included to initialize it to 0/false. So FYI, the best solution will involve the use of the window object!
J
Joseph Gabriel

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
}

This is underrated and IMHO a preferable way to check for something being undefined.
Absolutely correct, but I imagine if undefined !== void 0, you likely have other serious problems in said codebase.
And it exposes to throwing error when myVar has not been previously declared.
P
Peter Mortensen

Since none of the other answers helped me, I suggest doing this. It worked for me in Internet Explorer 8:

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

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

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

}

P
Peter Mortensen

On the contrary of @Thomas Eding answer:

If I forget to declare myVar in my code, then I'll get myVar is not defined.

Let's take a real example:

I've a variable name, but I am not sure if it is declared somewhere or not.

Then @Anurag's answer will help:

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.");

Getting such a myVar is not defined error would be a good thing then, especially when you specifically write "If i forget to declare" [emphasis mine]. I love it when I get errors before my code runs. If you care to see more of my opinion on your answer, I've made relevant comments under my answer.
P
Peter Mortensen
    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 

C
Cristian Sanchez

I use it as a function parameter and exclude it on function execution that way I get the "real" undefined. Although it does require you to put your code inside a function. I found this while reading the jQuery source.

undefined = 2;

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

Of course you could just use typeof though. But all my code is usually inside a containing function anyways, so using this method probably saves me a few bytes here and there.


It will give ReferenceError if the var undeclaredvar is really undeclared. It this is attribute - then it works, example: var undeclaredvar = window.someUndeclaredVar; if (undeclaredvar === undefined) console.log("it works!"). Please test you example before posting.