Detecting an undefined object property

后端 未结 30 2841
花落未央
花落未央 2020-11-21 04:43

What\'s the best way of checking if an object property in JavaScript is undefined?

相关标签:
30条回答
  • 2020-11-21 05:23
    "propertyName" in obj //-> true | false
    
    0 讨论(0)
  • 2020-11-21 05:25

    Reading through this, I'm amazed I didn't see this. I have found multiple algorithms that would work for this.

    Never Defined

    If the value of an object was never defined, this will prevent from returning true if it is defined as null or undefined. This is helpful if you want true to be returned for values set as undefined

    if(obj.prop === void 0) console.log("The value has never been defined");
    

    Defined as undefined Or never Defined

    If you want it to result as true for values defined with the value of undefined, or never defined, you can simply use === undefined

    if(obj.prop === undefined) console.log("The value is defined as undefined, or never defined");
    

    Defined as a falsy value, undefined,null, or never defined.

    Commonly, people have asked me for an algorithm to figure out if a value is either falsy, undefined, or null. The following works.

    if(obj.prop == false || obj.prop === null || obj.prop === undefined) {
        console.log("The value is falsy, null, or undefined");
    }
    
    0 讨论(0)
  • 2020-11-21 05:26

    I believe there are a number of incorrect answers to this topic. Contrary to common belief, "undefined" is not a keyword in JavaScript and can in fact have a value assigned to it.

    Correct Code

    The most robust way to perform this test is:

    if (typeof myVar === "undefined")
    

    This will always return the correct result, and even handles the situation where myVar is not declared.

    Degenerate code. DO NOT USE.

    var undefined = false;  // Shockingly, this is completely legal!
    if (myVar === undefined) {
        alert("You have been misled. Run away!");
    }
    

    Additionally, myVar === undefined will raise an error in the situation where myVar is undeclared.

    0 讨论(0)
  • 2020-11-21 05:26
    if ( typeof( something ) == "undefined") 
    

    This worked for me while the others didn't.

    0 讨论(0)
  • 2020-11-21 05:26

    If you do

    if (myvar == undefined )
    { 
        alert('var does not exists or is not initialized');
    }
    

    it will fail when the variable myvar does not exists, because myvar is not defined, so the script is broken and the test has no effect.

    Because the window object has a global scope (default object) outside a function, a declaration will be 'attached' to the window object.

    For example:

    var myvar = 'test';
    

    The global variable myvar is the same as window.myvar or window['myvar']

    To avoid errors to test when a global variable exists, you better use:

    if(window.myvar == undefined )
    { 
        alert('var does not exists or is not initialized');
    }
    

    The question if a variable really exists doesn't matter, its value is incorrect. Otherwise, it is silly to initialize variables with undefined, and it is better use the value false to initialize. When you know that all variables that you declare are initialized with false, you can simply check its type or rely on !window.myvar to check if it has a proper/valid value. So even when the variable is not defined then !window.myvar is the same for myvar = undefined or myvar = false or myvar = 0.

    When you expect a specific type, test the type of the variable. To speed up testing a condition you better do:

    if( !window.myvar || typeof window.myvar != 'string' )
    {
        alert('var does not exists or is not type of string');
    }
    

    When the first and simple condition is true, the interpreter skips the next tests.

    It is always better to use the instance/object of the variable to check if it got a valid value. It is more stable and is a better way of programming.

    (y)

    0 讨论(0)
  • 2020-11-21 05:27

    Despite being vehemently recommended by many other answers here, typeof is a bad choice. It should never be used for checking whether variables have the value undefined, because it acts as a combined check for the value undefined and for whether a variable exists. In the vast majority of cases, you know when a variable exists, and typeof will just introduce the potential for a silent failure if you make a typo in the variable name or in the string literal 'undefined'.

    var snapshot = …;
    
    if (typeof snaposhot === 'undefined') {
        //         ^
        // misspelled¹ – this will never run, but it won’t throw an error!
    }
    
    var foo = …;
    
    if (typeof foo === 'undefned') {
        //                   ^
        // misspelled – this will never run, but it won’t throw an error!
    }
    

    So unless you’re doing feature detection², where there’s uncertainty whether a given name will be in scope (like checking typeof module !== 'undefined' as a step in code specific to a CommonJS environment), typeof is a harmful choice when used on a variable, and the correct option is to compare the value directly:

    var foo = …;
    
    if (foo === undefined) {
        ⋮
    }
    

    Some common misconceptions about this include:

    • that reading an “uninitialized” variable (var foo) or parameter (function bar(foo) { … }, called as bar()) will fail. This is simply not true – variables without explicit initialization and parameters that weren’t given values always become undefined, and are always in scope.

    • that undefined can be overwritten. It’s true that undefined isn’t a keyword, but it is read-only and non-configurable. There are other built-ins you probably don’t avoid despite their non-keyword status (Object, Math, NaN…) and practical code usually isn’t written in an actively malicious environment, so this isn’t a good reason to be worried about undefined. (But if you are writing a code generator, feel free to use void 0.)

    With how variables work out of the way, it’s time to address the actual question: object properties. There is no reason to ever use typeof for object properties. The earlier exception regarding feature detection doesn’t apply here – typeof only has special behaviour on variables, and expressions that reference object properties are not variables.

    This:

    if (typeof foo.bar === 'undefined') {
        ⋮
    }
    

    is always exactly equivalent to this³:

    if (foo.bar === undefined) {
        ⋮
    }
    

    and taking into account the advice above, to avoid confusing readers as to why you’re using typeof, because it makes the most sense to use === to check for equality, because it could be refactored to checking a variable’s value later, and because it just plain looks better, you should always use === undefined³ here as well.

    Something else to consider when it comes to object properties is whether you really want to check for undefined at all. A given property name can be absent on an object (producing the value undefined when read), present on the object itself with the value undefined, present on the object’s prototype with the value undefined, or present on either of those with a non-undefined value. 'key' in obj will tell you whether a key is anywhere on an object’s prototype chain, and Object.prototype.hasOwnProperty.call(obj, 'key') will tell you whether it’s directly on the object. I won’t go into detail in this answer about prototypes and using objects as string-keyed maps, though, because it’s mostly intended to counter all the bad advice in other answers irrespective of the possible interpretations of the original question. Read up on object prototypes on MDN for more!

    ¹ unusual choice of example variable name? this is real dead code from the NoScript extension for Firefox.
    ² don’t assume that not knowing what’s in scope is okay in general, though. bonus vulnerability caused by abuse of dynamic scope: Project Zero 1225
    ³ once again assuming an ES5+ environment and that undefined refers to the undefined property of the global object.

    0 讨论(0)
提交回复
热议问题