关于javascript:检测未定义的对象属性

Detecting an undefined object property

检查javascript中的对象属性是否未定义的最佳方法是什么?


用途:

1
2
3
if (typeof something ==="undefined") {
    alert("something is undefined");
}

如果对象变量具有某些属性,则可以使用如下相同的内容:

1
2
3
if (typeof my_obj.someproperties ==="undefined"){
    console.log('the property is not available...'); // print into console
}


我相信这个话题有很多不正确的答案。与通常的看法相反,"未定义"不是javascript中的关键字,实际上可以为其分配一个值。

正确代码

执行此测试最可靠的方法是:

1
if (typeof myVar ==="undefined")

这将始终返回正确的结果,甚至处理未声明myVar的情况。

退化代码。不要使用。

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

此外,在未声明myvar的情况下,myVar === undefined会导致错误。


尽管这里有许多其他答案强烈推荐,但typeof是一个糟糕的选择。它不应用于检查变量是否具有值undefined,因为它是对值undefined和变量是否存在的组合检查。在绝大多数情况下,您知道变量何时存在,如果您在变量名或字符串文字'undefined'中输入错误,typeof只会引入无声失败的可能性。

1
2
3
4
5
6
var snapshot =;

if (typeof snaposhot === 'undefined') {
    //         ^
    // misspelled1 – this will never run, but it won’t throw an error!
}
1
2
3
4
5
6
var foo =;

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

因此,除非您正在进行功能检测2,如果不确定给定名称是否在范围内(例如检查typeof module !== 'undefined'作为特定于CommonJS环境的代码步骤),那么在变量上使用typeof是一个有害的选择,正确的选择是直接比较该值:

1
2
3
4
5
var foo =;

if (foo === undefined) {
    ?
}

关于这方面的一些常见误解包括:

  • 读取"未初始化"变量(var foo或参数(function bar(foo) { … }称为bar())将失败。这不是真的——没有显式初始化的变量和没有给定值的参数总是变成undefined,并且总是在范围内。

  • 可以覆盖undefined。还有很多。undefined不是javascript中的关键字。相反,它是具有未定义值的全局对象的属性。但是,自ES5以来,此属性是只读的,不可配置。现代浏览器不允许更改undefined属性,截至2017年,这种情况已经持续了很长时间。缺乏严格的模式也不会影响undefined的行为——它只是让像undefined = 5这样的语句不做任何事情,而不是抛出。但是,由于它不是关键字,因此可以声明名为undefined的变量,这些变量可以更改,使之成为一种常见的模式:

    1
    2
    3
    (function (undefined) {
        // …
    })()

    比使用全球undefined更危险。如果您必须与ES3兼容,请用void 0替换undefined–不要使用typeof。(void始终是一元运算符,计算任何操作数的未定义值。)

变量是如何工作的,是时候解决实际问题了:对象属性。没有理由将typeof用于对象属性。前面关于特征检测的异常在这里不适用——typeof只在变量上有特殊的行为,引用对象属性的表达式不是变量。

这是:

1
2
3
if (typeof foo.bar === 'undefined') {
    ?
}

始终完全等同于这3:

1
2
3
if (foo.bar === undefined) {
    ?
}

考虑到上面的建议,为了避免混淆读者为什么要使用typeof,因为使用===检查是否相等是最有意义的,因为它可以重构为稍后检查变量的值,并且因为它看起来很简单,所以在这里也应该始终使用=== undefined3。

当涉及到对象属性时,还需要考虑是否确实要检查undefined。给定的属性名可以在对象上不存在(读取时产生值undefined),在对象本身上存在值undefined,在对象的原型上存在值undefined,或者在具有非undefined值的任何一个上存在。'key' in obj将告诉您密钥是否在对象原型链上的任何位置,Object.prototype.hasOwnProperty.call(obj, 'key')将告诉您密钥是否直接在对象上。不过,我不会在这个答案中详细讨论原型和使用对象作为字符串键映射,因为它主要是为了反驳其他答案中的所有错误建议,而不管原始问题的可能解释如何。了解更多有关MDN上对象原型的信息!

1示例变量名的异常选择?这是来自firefox noscript扩展的真正死代码。2不要假设不知道什么在范围内一般是可以的。滥用动态范围导致的额外漏洞:Project Zero 12253再次假设一个ES5+环境,并且undefined引用全局对象的undefined属性。替换void 0,否则。


在javascript中有空值和未定义值。它们有不同的含义。

  • 未定义表示变量值尚未定义;不知道值是什么。
  • 空表示变量值已定义并设置为空(没有值)。

Marijn Haverbeke在他的免费在线书籍"雄辩的javascript"(Emphasis Mine)中说:

There is also a similar value, null, whose meaning is 'this value is defined, but it does not have a value'. The difference in meaning between undefined and null is mostly academic, and usually not very interesting. In practical programs, it is often necessary to check whether something 'has a value'. In these cases, the expression something == undefined may be used, because, even though they are not exactly the same value, null == undefined will produce true.

因此,我想检查未定义内容的最佳方法是:

1
if (something == undefined)

希望这有帮助!

编辑:响应您的编辑,对象属性应该以相同的方式工作。

1
2
3
4
5
6
7
8
var person = {
    name:"John",
    age: 28,
    sex:"male"
};

alert(person.name); //"John"
alert(person.fakeVariable); // undefined


这是什么意思:"未定义的对象属性"?

实际上,它可能意味着两件完全不同的事情!首先,它可以表示对象中从未定义的属性,其次,它可以表示具有未定义值的属性。让我们看看这段代码:

1
var o = { a: undefined }

o.a是否未定义?对!其值未定义。o.b是否未定义?当然!根本没有"B"属性!好的,现在看看不同的方法在这两种情况下的行为:

1
2
3
4
5
6
typeof o.a == 'undefined' // true
typeof o.b == 'undefined' // true
o.a === undefined // true
o.b === undefined // true
'a' in o // true
'b' in o // false

我们可以清楚地看到,typeof obj.prop == 'undefined'obj.prop === undefined是等效的,它们不区分不同的情况。而'prop' in obj可以检测到一个属性根本没有定义,也不注意可能没有定义的属性值的情况。

那么该怎么办呢?

1)您想知道属性是否由第一个或第二个含义(最典型的情况)定义。

1
obj.prop === undefined // IMHO, see"final fight" below

2)您只想知道对象是否具有某些属性,而不关心它的值。

1
'prop' in obj

笔记:

  • 不能同时检查对象及其属性。例如,如果x没有定义,那么这个x.a === undefined或这个typeof x.a == 'undefined'会提升ReferenceError: x is not defined
  • 变量undefined是一个全局变量(实际上浏览器中是window.undefined)。它自ECMAScript第1版起得到支持,自ECMAScript 5起为只读。因此,在现代浏览器中,它不能被重新定义为"真",因为许多作者喜欢用它来吓唬我们,但对于老浏览器来说,这仍然是真的。

最后一战:江户十一〔3〕对江户十一〔2〕的较量

obj.prop === undefined的优点:

  • 它有点短,看起来更漂亮
  • 如果您拼错了undefined,javascript引擎会给您一个错误。

obj.prop === undefined的减数:

  • 在旧浏览器中可以覆盖undefined

typeof obj.prop == 'undefined'的优点:

  • 它真的很普遍!它可以在新的和旧的浏览器中工作。

typeof obj.prop == 'undefined'的减数:

  • EDOCX1(拼写错误)这里只是一个字符串常量,所以如果你像我刚才那样拼写错误,javascript引擎就帮不了你了。

更新(针对服务器端javascript):

node.js支持全局变量undefined作为global.undefined使用(也可以不使用"global"前缀)。我不知道服务器端JavaScript的其他实现。


这个问题归结为三种情况:

  • 对象具有该属性,其值不是undefined
  • 对象具有该属性,其值为undefined
  • 对象没有属性。
  • 这告诉我们一些我认为重要的事情:

    未定义成员和具有未定义值的已定义成员之间存在差异。

    但不幸的是,typeof obj.foo并没有告诉我们三个案例中的哪一个。然而,我们可以将其与"foo" in obj结合起来区分这些病例。

    1
    2
    3
    4
                                   |  typeof obj.x === 'undefined' | !("x" in obj)
    1.                     { x:1 } |  false                        | false
    2.    { x : (function(){})() } |  true                         | false
    3.                          {} |  true                         | true

    值得注意的是,这些测试对于null条目也是一样的。

    1
    2
                                   |  typeof obj.x === 'undefined' | !("x" in obj)
                        { x:null } |  false                        | false

    我认为,在某些情况下,检查属性是否存在比检查它是否未定义更有意义(而且更清楚),唯一不同的情况是第2种情况,即对象中具有未定义值的实际条目的罕见情况。

    例如:我刚刚重构了一组代码,这些代码检查对象是否具有给定的属性。

    1
    if( typeof blob.x != 'undefined' ) {  fn(blob.x); }

    在没有未定义的支票的情况下写的更清楚。

    1
    if("x" in blob ) { fn(blob.x); }

    但正如前面所提到的,这些并不完全相同(但足以满足我的需要)。


    1
    if ( typeof( something ) =="undefined")

    这对我有效,而其他人则没有。


    我不确定使用===typeof的起源是从哪里来的,作为一种惯例,我看到它在许多库中使用,但是type of运算符返回一个字符串文本,我们知道前面的内容,那么为什么还要键入check呢?

    1
    2
    3
    typeof x;                      // some string literal"string","object","undefined"
    if (typeof x ==="string") {   // === is redundant because we already know typeof returns a string literal
    if (typeof x =="string") {    // sufficient


    从相关问题交叉发布我的答案如何检查javascript中的"未定义"?

    针对这个问题,请参见使用someObject.的测试用例。

    说明各种答案结果的一些场景:http://jsfiddle.net/drzaus/uvjm4/

    (注意,在作用域包装中,使用var进行in测试会产生差异)

    参考代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    (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 +="
    "
    + tests[t] +":" + result;
        }
    })();

    结果:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    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

    如果你这样做了

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

    当变量myvar不存在时,它将失败,因为myvar没有定义,所以脚本被破坏,测试没有效果。

    因为window对象在函数外部有一个全局范围(默认对象),所以声明将"附加"到window对象。

    例如:

    1
    var myvar = 'test';

    全局变量myvar与window.myvar或window[‘myvar’]相同

    为了避免在存在全局变量时测试错误,最好使用:

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

    如果一个变量真的存在,这个问题并不重要,它的值是不正确的。否则,初始化未定义的变量是愚蠢的,最好使用值false初始化。当您知道您声明的所有变量都初始化为false时,您可以简单地检查它的类型或依赖于!window.myvar来检查它是否具有正确/有效的值。因此,即使未定义变量,!window.myvar对于myvar = undefinedmyvar = falsemyvar = 0也是相同的。

    当需要特定类型时,测试变量的类型。要加快测试条件,最好:

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

    当第一个简单条件为真时,解释器跳过下一个测试。

    最好使用变量的实例/对象来检查它是否有有效的值。它更稳定,是更好的编程方法。

    (Y)


    我没看见(希望我没错过)有人在房产前检查过这个东西。因此,这是最短和最有效的(尽管不一定是最清楚的):

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

    如果obj或obj.prop未定义、为空或"falsy",if语句将不执行代码块。这通常是大多数代码块语句(在javascript中)所期望的行为。


    在探索javascript中的空和未定义的深渊的文章中,我了解到像underline.js这样的框架使用此函数:

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


    'if(window.x)'是错误安全的

    很可能你想要if (window.x)。即使没有声明X(var x;号),这种检查也是安全的——浏览器不会抛出错误。

    示例:我想知道我的浏览器是否支持历史API

    1
    2
    3
    if (window.history) {
        history.call_some_function();
    }

    如何运作:

    窗口是一个将所有全局变量作为其成员的对象,尝试访问一个不存在的成员是合法的。如果x未声明或未设置,那么window.x返回未定义。当if()对其进行计算时,未定义将导致false。


    1
    "propertyName" in obj //-> true | false


    读完这篇文章,我很惊讶我没有看到这个。我发现了多种算法可以解决这个问题。

    未曾定义

    如果一个对象的值从未被定义过,如果它被定义为nullundefined的话,这将阻止返回true。如果您希望为设置为undefined的值返回true,这将非常有用。

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

    定义为未定义或从未定义

    如果您希望使用undefined值定义的值或从未定义的值的结果为true,您可以简单地使用=== undefined

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

    定义为错误值、未定义、空或从未定义。

    通常,人们会要求我使用一种算法来计算一个值是否是falsy、undefinednull。以下工作。

    1
    2
    3
    if(obj.prop == false || obj.prop === null || obj.prop === undefined) {
        console.log("The value is falsy, null, or undefined");
    }


    您可以使用下面的代码获取一个未定义的数组,其中包含路径。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
     function getAllUndefined(object) {

            function convertPath(arr, key) {
                var path ="";
                for (var i = 1; i < arr.length; i++) {

                    path += arr[i] +"->";
                }
                path += key;
                return path;
            }


            var stack = [];
            var saveUndefined= [];
            function getUndefiend(obj, key) {

                var t = typeof obj;
                switch (t) {
                    case"object":
                        if (t === null) {
                            return false;
                        }
                        break;
                    case"string":
                    case"number":
                    case"boolean":
                    case"null":
                        return false;
                    default:
                        return true;
                }
                stack.push(key);
                for (k in obj) {
                    if (obj.hasOwnProperty(k)) {
                        v = getUndefiend(obj[k], k);
                        if (v) {
                            saveUndefined.push(convertPath(stack, k));
                        }
                    }
                }
                stack.pop();

            }

            getUndefiend({
               "": object
            },"");
            return saveUndefined;
        }

    JSFIDLE链路


    简单地说,任何东西都没有在javascript中定义,没有定义,不管它是对象/数组中的属性还是简单变量…

    javascript有typeof,这使得检测未定义变量非常容易。

    只需检查typeof whatever === 'undefined'是否返回布尔值。

    这就是AngularJS v.1X中著名的函数isUndefined()的写作方式:

    1
    function isUndefined(value) {return typeof value === 'undefined';}

    因此,正如您看到的,函数接收一个值,如果定义了该值,它将返回false,否则对于未定义的值,返回true

    让我们看看当我们传递值时会得到什么结果,包括下面的对象属性,这是我们拥有的变量列表:

    1
    2
    3
    4
    5
    6
    7
    var stackoverflow = {};
    stackoverflow.javascipt = 'javascript';
    var today;
    var self = this;
    var num = 8;
    var list = [1, 2, 3, 4, 5];
    var y = null;

    我们检查它们如下,您可以看到它们前面的结果作为注释:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    isUndefined(stackoverflow); //false
    isUndefined(stackoverflow.javascipt); //false
    isUndefined(today); //true
    isUndefined(self); //false
    isUndefined(num); //false
    isUndefined(list); //false
    isUndefined(y); //false
    isUndefined(stackoverflow.java); //true
    isUndefined(stackoverflow.php); //true
    isUndefined(stackoverflow && stackoverflow.css); //true

    正如您所看到的,我们可以在代码中使用类似的东西来检查任何东西,正如前面提到的,您可以在代码中简单地使用typeof,但是如果您反复使用它,请创建一个类似于角形示例的函数,我共享它,并按照干燥的代码模式继续重用它。

    还有一件事,要检查实际应用程序中对象的属性,即使对象是否存在,也要先检查对象是否存在。

    如果检查对象上的属性而该对象不存在,则将引发错误并停止整个应用程序的运行。

    1
    2
    isUndefined(x.css);
    VM808:2 Uncaught ReferenceError: x is not defined()

    如此简单,您可以像下面这样包装在if语句中:

    1
    2
    3
    if(typeof x !== 'undefined') {
      //do something
    }

    也等于在角1.x中定义的。

    1
    function isDefined(value) {return typeof value !== 'undefined';}

    其他的javascript框架(如下划线)也有类似的定义检查,但我建议您使用typeof,如果您已经不使用任何框架。

    我还添加了MDN中的这个部分,它获得了关于typeof、undefined和void(0)的有用信息。

    Strict equality and undefined You can use undefined and the strict equality and inequality operators to determine whether a variable has
    a value. In the following code, the variable x is not defined, and the
    if statement evaluates to true.

    1
    2
    3
    4
    5
    6
    7
    var x;
    if (x === undefined) {
       // these statements execute
    }
    else {
       // these statements do not execute
    }

    Note: The strict equality operator rather than the standard equality
    operator must be used here, because x == undefined also checks whether
    x is null, while strict equality doesn't. null is not equivalent to
    undefined. See comparison operators for details.

    Typeof operator and undefined
    Alternatively, typeof can be used:

    1
    2
    3
    4
    var x;
    if (typeof x === 'undefined') {
       // these statements execute
    }

    One reason to use typeof is that it does not throw an error if the
    variable has not been declared.

    1
    2
    3
    4
    5
    6
    7
    8
    // x has not been declared before
    if (typeof x === 'undefined') { // evaluates to true without errors
       // these statements execute
    }

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

    }

    However, this kind of technique should be avoided. JavaScript is a
    statically scoped language, so knowing if a variable is declared can
    be read by seeing whether it is declared in an enclosing context. The
    only exception is the global scope, but the global scope is bound to
    the global object, so checking the existence of a variable in the
    global context can be done by checking the existence of a property on
    the global object (using the in operator, for instance).

    Void operator and undefined

    The void operator is a third alternative.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    var x;
    if (x === void 0) {
       // these statements execute
    }

    // y has not been declared before
    if (y === void 0) {
       // throws a ReferenceError (in contrast to `typeof`)
    }

    这里更


    void 0相比,简洁明了。

    1
    if (foo !== void 0)

    它不像if (typeof foo !== 'undefined')那样冗长。


    解决方案不正确。在JavaScript中,

    1
    null == undefined

    将返回true,因为它们都被"强制"为布尔值且为false。正确的方法是检查

    1
    if (something === undefined)

    哪个是身份操作员…


    如果定义了一个新变量,有一种很好且优雅的方法可以将一个已定义的属性分配给它;如果定义了一个新变量,可以将默认值分配给它作为回退。

    1
    var a = obj.prop || defaultValue;

    如果您有一个函数,它接收到一个额外的配置属性,那么它是合适的:

    1
    2
    3
    4
    5
    6
    7
    var yourFunction = function(config){

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

    }

    现在执行

    1
    2
    3
    4
    5
    6
    7
    8
    yourFunction({yourConfigValue:2});
    //=> 2

    yourFunction();
    //=> 1

    yourFunction({otherProperty:5});
    //=> 1

    我的情况是:

    我正在使用REST调用的结果。结果应该从JSON解析到一个javascript对象。

    我需要为一个错误辩护。如果对REST调用的参数不正确,只要用户指定了错误的参数,那么REST调用基本上是空的。

    当我使用这篇文章来帮助我抵御这种情况时,我尝试了这个方法。

    1
    if( typeof restResult.data[0] ==="undefined" ) { throw "Some error"; }

    对于我的情况,如果restresult.data[0]=="object",那么我可以安全地开始检查其他成员。如果未定义,则如上所述抛出错误。

    我要说的是,对于我的情况,上述所有建议在这篇文章中都不起作用。我不是说我是对的,每个人都是错的。我根本不是一个javascript大师,但希望这能帮助一些人。


    如果使用角度:

    1
    2
    angular.isUndefined(obj)
    angular.isUndefined(obj.prop)

    Underscore.js:

    1
    2
    _.isUndefined(obj)
    _.isUndefined(obj.prop)


    浏览注释,对于那些想要同时检查这两者的人,它是未定义的还是其值为空:

    1
    2
    3
    4
    5
    //Just in JavaScript
    var s; // Undefined
    if (typeof s =="undefined" || s === null){
        alert('either it is undefined or value is null')
    }

    如果您使用的是jquery库,那么jQuery.isEmptyObject()将足以满足这两种情况,

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    var s; // Undefined
    jQuery.isEmptyObject(s); // Will return true;

    s = null; // Defined as null
    jQuery.isEmptyObject(s); // Will return true;

    //Usage
    if (jQuery.isEmptyObject(s)) {
        alert('Either variable:s is undefined or its value is null');
    } else {
         alert('variable:s has value ' + s);
    }

    s = 'something'; // Defined with some value
    jQuery.isEmptyObject(s); // Will return false;


    所有答案都不完整。这是知道存在"定义为未定义"的属性的正确方法:

    1
    2
    3
    var hasUndefinedProperty = function hasUndefinedProperty(obj, prop){
      return ((prop in obj) && (typeof obj[prop] == 'undefined')) ;
    } ;

    例子:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    var a = { b : 1, e : null } ;
    a.c = a.d ;

    hasUndefinedProperty(a, 'b') ; // false : b is defined as 1
    hasUndefinedProperty(a, 'c') ; // true : c is defined as undefined
    hasUndefinedProperty(a, 'd') ; // false : d is undefined
    hasUndefinedProperty(a, 'e') ; // false : e is defined as null

    // And now...
    delete a.c ;
    hasUndefinedProperty(a, 'c') ; // false : c is undefined

    太糟糕了,这是正确的答案埋在错误的答案中>。_<

    所以,对于任何路过的人,我会免费给你不光彩的东西!!

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    var undefined ; undefined ; // undefined
    ({}).a ;                    // undefined
    [].a ;                      // undefined
    ''.a ;                      // undefined
    (function(){}()) ;          // undefined
    void(0) ;                   // undefined
    eval() ;                    // undefined
    1..a ;                      // undefined
    /a/.a ;                     // undefined
    (true).a ;                  // undefined


    我用if (this.variable)来测试是否有定义。上面推荐的简单的if (variable)对我来说是失败的。结果表明,只有当变量是某个对象的字段(obj.someField)时,它才起作用,以检查它是否在字典中定义。但是我们可以使用thiswindow作为字典对象,因为我理解,任何变量都是当前窗口中的字段。因此这里有一个测试

    1
    2
    3
    4
    if (this.abc) alert("defined"); else alert("undefined");

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

    它首先检测到变量abc未定义,并在初始化后定义。


    1
    2
    3
    function isUnset(inp) {
      return (typeof inp === 'undefined')
    }

    如果设置了变量,则返回false;如果未定义,则返回true。

    然后使用:

    1
    2
    3
    if (isUnset(var)) {
      // initialize variable here
    }


    我为那些期待奇怪答案的人提供了三种方法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    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);

    ISunDeald1:

    尝试获取输入值的属性,检查错误消息是否存在。如果输入值未定义,则错误消息将是未捕获的类型错误:无法读取未定义的属性"b"

    ISunDeald2:

    将输入值转换为字符串以与"undefined"进行比较,并确保其为负值。

    ISunDeald3:

    在JS中,当输入值正好是undefined时,可选参数工作。


    同样的事情也可以写得更短:

    1
    2
    3
    if (!variable){
        //do it if variable is Undefined
    }

    1
    2
    3
    if (variable){
        //do it if variable is Defined
    }


    来自房舍。

    1
    2
    3
    4
    var undefined;
    function isUndefined(value) {
      return value === undefined;
    }

    它创建一个名为undefined的局部变量,该变量初始化为默认值——实际undefined,然后将value与变量undefined进行比较。


    为了保护undefined变量,我想向您展示一些我正在使用的东西:

    1
    Object.defineProperty(window, 'undefined', {});

    这禁止任何人更改window.undefined值,因此会基于该变量破坏代码。如果使用"use strict",任何试图更改其值的操作都将以错误结束,否则将被静默忽略。


    您也可以使用代理,它将与嵌套调用一起工作,但需要额外检查:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    function resolveUnknownProps(obj, resolveKey) {
      const handler = {
        get(target, key) {
          if (
            target[key] !== null &&
            typeof target[key] === 'object'
          ) {
            return resolveUnknownProps(target[key], resolveKey);
          } else if (!target[key]) {
            return resolveUnknownProps({ [resolveKey]: true }, resolveKey);
          }

          return target[key];
        },
      };

      return new Proxy(obj, handler);
    }

    const user = {}

    console.log(resolveUnknownProps(user, 'isUndefined').personalInfo.name.something.else); // { isUndefined: true }

    所以你会像这样使用它:

    1
    2
    3
    4
    const { isUndefined } = resolveUnknownProps(user, 'isUndefined').personalInfo.name.something.else;
    if (!isUndefined) {
      // do someting
    }

    用途:

    要检查属性是否未定义:

    1
    2
    3
    if (typeof something ==="undefined") {
        alert("undefined");
    }

    要检查属性是否未定义:

    1
    2
    3
    if (typeof something !=="undefined") {
        alert("not undefined");
    }

    我很惊讶我还没有看到这个建议,但它比用typeof测试更具特异性。如果需要知道对象属性是用undefined初始化的还是从未初始化的,请使用Object.getOwnPropertyDescriptor()

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    // to test someObject.someProperty
    var descriptor = Object.getOwnPropertyDescriptor(someObject, 'someProperty');

    if (typeof descriptor === 'undefined') {
      // was never initialized
    } else if (typeof descriptor.value === 'undefined') {
      if (descriptor.get || descriptor.set) {
        // is an accessor property, defined via getter and setter
      } else {
        // is initialized with `undefined`
      }
    } else {
      // is initialized with some other value
    }

    我假设你还想检查一下它是undefined还是null。如果是,我建议:

    myVar == null

    这是唯一一次双等号非常有用,因为当myVarundefinednull时,它将对true进行评估,但当它是其他虚假值(如0false''NaN时,它将对false进行评估。

    这是lodash的isNil方法的实际源代码。


    您可以这样使用javascript对象函数:

    1
    2
    3
    4
    5
    6
    7
    var ojb ={
        age:12
    }

    if(ojb.hasOwnProperty('name')){
        console.log('property exist and not undefined');
    }

    如果上述方法得到未定义的属性或属性,则返回true


    在罗达什图书馆有几个小帮手:

    i默认-检查值是否为undefined

    1
    2
    _.isUndefined(undefined) // => true
    _.isUndefined(null) // => false

    has-检查对象是否包含属性

    1
    2
    3
    4
    const object = { 'a': { 'b': 2 } }

    _.has(object, 'a.b') // => true
    _.has(object, 'a.c') // => false

    检查密钥是否存在的一个简单方法是使用in

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    if (key in obj) {
      // do something
    } else {
      // create key
    }

    const obj = {
      0: 'abc',
      1: 'def'
    }

    const hasZero = 0 in obj

    console.log(hasZero) // true

    在ecmascript 6中引入,我们现在可以使用代理以新的方式处理undefined。它可以用于为不存在的任何属性设置默认值,这样我们就不必每次都检查它是否实际存在。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    var handler = {
      get: function(target, name) {
        return name in target ? target[name] : 'N/A';
      }
    };

    var p = new Proxy({}, handler);
    p.name = 'Kevin';
    console.log('Name: ' +p.name, ', Age: '+p.age, ', Gender: '+p.gender)

    将输出下面的文本而不获取任何未定义的内容。

    1
    Name: Kevin , Age: N/A , Gender: N/A

    这可能是确定现有属性名是否具有明确的预期值undefined的唯一明确形式;尽管如此,这是一种JS类型。

    1
    2
    "propertyName" in containerObject &&""+containerObject["propertyName"] =="undefined";
    >> true \ false

    如果给定上下文的属性名存在(真实存在),并且其预期值显式为undefined,则此表达式将只返回true

    不会有像空或空字符串零、空或空数组之类的误报。就是这样。检查,即,确保属性名存在(否则将是误报),而不是显式检查其值是否为undefined,例如,在其字符串表示形式中的未定义JS类型(字面上为"未定义"),因此==而不是===因为无法进一步转换。只有同时满足这两个条件,即满足所有条件,此表达式才会返回true。例如,如果属性名不存在,-它将返回false。这是唯一正确的返回,因为不存在的属性不能有值,甚至不能有未定义的值。

    例子:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    containerObject = { propertyName: void"anything" }
    >> Object { propertyName: undefined }

    // now the testing

    "propertyName" in containerObject &&""+containerObject["propertyName"] =="undefined";
    >> true

    /* which makes sure that nonexistent property will not return a false positive
     * unless it is previously defined  */


    "foo" in containerObject &&""+containerObject["foo"] =="undefined";
    >> false


    Object.hasOwnProperty(o, 'propertyname');

    然而,这并不是通过原型链来查找的。


    1
    2
    3
    if (somevariable == undefined) {
      alert('the variable is not defined!');
    }

    您还可以将其设置为一个函数,如下所示:

    1
    2
    3
    function isset(varname){
      return(typeof(window[varname]) != 'undefined');
    }