Detecting an undefined object property

后端 未结 30 2850
花落未央
花落未央 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:30

    I didn't see (hope I didn't miss it) anyone checking the object before the property. So, this is the shortest and most effective (though not necessarily the most clear):

    if (obj && obj.prop) {
      // Do something;
    }
    

    If the obj or obj.prop is undefined, null, or "falsy", the if statement will not execute the code block. This is usually the desired behavior in most code block statements (in JavaScript).

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

    Crossposting my answer from related question How can I check for "undefined" in JavaScript?.

    Specific to this question, see test cases with someObject.<whatever>.


    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
    
    0 讨论(0)
  • 2020-11-21 05:34

    There is a nice and elegant way to assign a defined property to a new variable if it is defined or assign a default value to it as a fallback if it’s undefined.

    var a = obj.prop || defaultValue;
    

    It’s suitable if you have a function, which receives an additional configuration property:

    var yourFunction = function(config){
    
       this.config = config || {};
       this.yourConfigValue = config.yourConfigValue || 1;
       console.log(this.yourConfigValue);
    }
    

    Now executing

    yourFunction({yourConfigValue:2});
    //=> 2
    
    yourFunction();
    //=> 1
    
    yourFunction({otherProperty:5});
    //=> 1
    
    0 讨论(0)
  • 2020-11-21 05:34

    I provide three ways here for those who expect weird answers:

    function isUndefined1(val) {
        try {
            val.a;
        } catch (e) {
            return /undefined/.test(e.message);
        }
        return false;
    }
    
    function isUndefined2(val) {
        return !val && val+'' === 'undefined';
    }
    
    function isUndefined3(val) {
        const defaultVal = {};
        return ((input = defaultVal) => input === defaultVal)(val);
    }
    
    function test(func){
        console.group(`test start :`+func.name);
        console.log(func(undefined));
        console.log(func(null));
        console.log(func(1));
        console.log(func("1"));
        console.log(func(0));
        console.log(func({}));
        console.log(func(function () { }));
        console.groupEnd();
    }
    test(isUndefined1);
    test(isUndefined2);
    test(isUndefined3);

    isUndefined1:

    Try to get a property of the input value, and check the error message if it exists. If the input value is undefined, the error message would be Uncaught TypeError: Cannot read property 'b' of undefined.

    isUndefined2:

    Convert the input value to a string to compare with "undefined" and ensure it's a negative value.

    isUndefined3:

    In JavaScript, an optional parameter works when the input value is exactly undefined.

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

    If you are using Angular:

    angular.isUndefined(obj)
    angular.isUndefined(obj.prop)
    

    Underscore.js:

    _.isUndefined(obj) 
    _.isUndefined(obj.prop) 
    
    0 讨论(0)
  • 2020-11-21 05:36

    I use if (this.variable) to test if it is defined. A simple if (variable), recommended in a previous answer, fails for me.

    It turns out that it works only when a variable is a field of some object, obj.someField to check if it is defined in the dictionary. But we can use this or window as the dictionary object since any variable is a field in the current window, as I understand it. Therefore here is a test:

    if (this.abc) 
        alert("defined"); 
    else 
        alert("undefined");
    
    abc = "abc";
    if (this.abc) 
        alert("defined"); 
    else 
        alert("undefined");

    It first detects that variable abc is undefined and it is defined after initialization.

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