检测未定义的对象属性

Detecting an undefined object property

提问人:Matt Sheppard 提问时间:8/26/2008 最后编辑:TylerHMatt Sheppard 更新时间:8/21/2023 访问量:1486570

问:

如何检查 JavaScript 中的对象属性是否未定义?

JavaScript 未定义的 对象属性

评论

0赞 AlejandroVD 8/24/2021
在此线程中查找最近的答案。在“现代”javascript 中,考虑使用运算符:in'key' in obj ? 'obj has key property' : 'obj does not have key property' `
0赞 Matt Sheppard 8/25/2021
如果您心中有一个与当前方式一样完整地涵盖旧方式并解决更现代选项的答案,我愿意选择一个新的“正确”答案。

答:

175赞 Pandincus 8/26/2008 #1

在 JavaScript 中,有 nullundefined。它们有不同的含义。

  • undefined 表示变量值尚未定义;目前尚不清楚该值是多少。
  • null 表示变量值已定义并设置为 null(没有值)。

Marijn Haverbeke 在他的免费在线书籍“Eloquent JavaScript”(强调我的)中说:

还有一个类似的值 null,其含义是“此值已定义,但它没有值”。undefined 和 null 之间的含义差异主要是学术性的,通常不是很有趣。在实际程序中,通常需要检查某物是否“有价值”。在这些情况下,可以使用表达式 something == undefined,因为即使它们不完全相同,null == undefined 也会生成 true。

所以,我想检查某些东西是否未定义的最佳方法是:

if (something == undefined)

对象属性应以相同的方式工作。

var person = {
    name: "John",
    age: 28,
    sex: "male"
};

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

评论

46赞 Sebastian Rittau 11/30/2009
if (something == undefined) 最好写成好像 (something === undefined)
61赞 Gabe Moothart 4/14/2010
应该指出的是,这并不完全安全。 只是一个可以由用户重新分配的变量:编写将导致你的代码不再做你认为它做的事情。使用更好,也适用于尚未声明的变量(而不仅仅是属性)。undefinedundefined = 'a';typeof
7赞 Morgan Cheng 4/21/2010
如果某物是未定义的全局变量,(某物==未定义)会引发 JavaScript 错误。
8赞 Andrew 5/20/2011
这样做的问题是,如果 var a = null,则 == undefined 的计算结果为 true,即使 a 肯定是定义的。
7赞 Chuck Kollars 5/18/2012
这种对“雄辩的 Javascript”注释的解释是倒退的。如果您真的只想检查未定义,则建议的代码将不起作用(它还将检测已定义的条件,但尚未同化任何值 [即 null]).a null 值。建议的代码“if (something == undefined) ...”检查 undefined 和 null(未设置值),即它被解释为“if ((something is undefined) OR (something is null)) ...”作者的意思是,通常您真正想要的是检查 undefined 和 null。
12赞 Ricky 8/26/2008 #2

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

null == undefined

将返回 true,因为它们都“强制转换”为布尔值并且为 false。正确的方法是检查

if (something === undefined)

哪个是身份运算符...

评论

3赞 clacke 7/30/2010
需要明确的是类型 equality +(基元相等 | 对象标识),其中基元包含字符串。我认为,如果一个人认为是身份运算符,大多数人都会认为这是不直观的。==='abab'.slice(0,2) === 'abab'.slice(2)===
1赞 Simon East 6/15/2011
错。如果尚未创建变量,则会引发错误。不应该被投票赞成。请改用 typeof。
0赞 Peter Mortensen 7/25/2020
什么解决方案?你能直接链接到它吗?
2934赞 Erwin 1/6/2009 #3

检查属性的值是否为特殊值的常用方法是:undefined

if(o.myProperty === undefined) {
  alert("myProperty value is the special value `undefined`");
}

要检查某个对象是否实际上没有这样的属性,因此在尝试访问它时将默认返回:undefined

if(!o.hasOwnProperty('myProperty')) {
  alert("myProperty does not exist");
}

要检查与标识符关联的值是否为特殊值,或者是否尚未声明该标识符:undefined

if(typeof myVariable === 'undefined') {
  alert('myVariable is either the special value `undefined`, or it has not been declared');
}

注意:最后一种方法是引用未声明的标识符而没有早期错误的唯一方法,这与值为 .undefined

在 ECMAScript 5 之前的 JavaScript 版本中,全局对象上名为“undefined”的属性是可写的,因此,如果意外地重新定义了简单的检查,则该检查可能会出现意外行为。在现代 JavaScript 中,该属性是只读的。foo === undefined

然而,在现代 JavaScript 中,“undefined”不是一个关键字,因此函数中的变量可以命名为“undefined”并隐藏全局属性。

如果您担心这种(不太可能的)边缘情况,您可以使用 void 运算符来获取特殊值本身:undefined

if(myVariable === void 0) {
  alert("myVariable is the special value `undefined`");
}

评论

10赞 neu-rah 6/26/2012
如果某物为 null,则将其定义为 null,但您可以共轭 too 检查。上面代码令人讨厌的细节是你不能定义一个函数来检查它,好吧你可以定义函数......但试着使用它。
6赞 Zack 9/25/2012
@neu-rah 为什么不能写函数?为什么这样的事情行不通?它似乎对我有用。有没有我不考虑的情况?jsfiddle.net/djH9N/6
8赞 pnkfelix 2/15/2013
@Zack 对 isNullorUndefined 的测试未考虑调用 isNullOrUndefined(f) 且 f 未声明(即没有“var f”声明)的情况。
144赞 Ry- 5/14/2014
等等,现在有数千张选票。这是最糟糕的方法。希望路人看到这条评论,决定检查一下......咳咳......其他答案。
22赞 Bruno Buccolo 3/16/2016
你现在可以用了。 过去是可变的,比如什么会引起有趣的结果。但是在 Ecmascript 5 之后,它不再是可写的,所以我们可以使用更简单的版本。codereadability.com/how-to-check-for-undefined-in-javascriptobj !== undefinedundefinedundefined = 1234
4赞 Rixius 7/13/2010 #4
function isUnset(inp) {
  return (typeof inp === 'undefined')
}

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

然后使用:

if (isUnset(var)) {
  // initialize variable here
}

评论

5赞 Stijn de Witt 11/1/2015
不。别这样。只需要一个非常简单的测试来证明你不能有意义地将测试包装在一个函数中。令人惊讶的是,有 4 个人对此投了赞成票。-1.typeof
48赞 Kevin 7/28/2010 #5
if ( typeof( something ) == "undefined") 

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

评论

50赞 aehlke 8/10/2010
由于 typeof 是运算符,因此不需要 paren
13赞 Abhi Beckert 9/6/2012
但是它们更清楚地表明了正在检查的内容。否则,它可能会被读取为 .typeof (something == "undefined")
0赞 Ian 3/8/2014
如果你需要括号,那么你应该学习 JS 中的运算符优先级:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
12赞 DaveWalley 4/11/2014
括号之所以有用,正是因为您不需要学习 JS 中的运算符优先级,也不需要推测未来的维护程序员是否需要学习 JS 中的运算符优先级。
31赞 Robert 5/15/2014
括号有助于澄清事情。但在这种情况下,它们只是使运算符看起来像一个函数。毫无疑问,这澄清了程序员的意图。但是,如果您不确定运算符的优先级,则应将其编写为 。(typeof something) === "undefined"
985赞 MarkPflug 8/24/2010 #6

我相信这个话题有很多不正确的答案。与普遍的看法相反,“undefined”在 JavaScript 中不是一个关键字,实际上可以为其分配一个值。

正确的代码

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

if (typeof myVar === "undefined")

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

退化代码。请勿使用。

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

此外,在未声明 myVar 的情况下将引发错误。myVar === undefined

评论

25赞 eis 8/20/2013
除了 Marks 评论之外,我还不明白:“myVar === undefined 会在 myVar 未声明的情况下引发错误。如果我引用未声明的变量,为什么我不想出现错误?
6赞 Claudiu 10/4/2013
另请记住,您始终可以这样做来获取指向的值。所以你可以做.这并不特别,你可以从字面上把任何表达放在那里。void 0undefinedif (myVar === void 0)0
35赞 user247702 2/7/2014
在现代浏览器(FF4+、IE9+、Chrome 未知)中,无法再修改 .MDN:未定义undefined
13赞 Zero3 12/15/2015
这个答案也是不正确的。问题是关于未定义的对象属性,而不是未定义的变量。有显着差异。例如,这样做是完全合理的.我认为有人这样做的风险被高估了。如果你想防止由糟糕的编程引起的所有此类副作用,你将不得不进行不合理的防御性编程。if (obj.field === undefined)var undefined = false;
10赞 12/18/2017
有趣的是,人们建议这些愚蠢且容易出错的黑客来避免阴影(这只能由糟糕的开发人员完成),但他们却轻率地使用其他也可能被阴影的全局标识符。奇怪。真是太奇怪了。undefined
44赞 Eric 9/22/2010 #7

我不确定使用 with 的起源是从哪里来的,作为一种惯例,我看到它在许多库中使用,但是 typeof 运算符返回一个字符串文字,我们事先知道这一点,那么为什么你也想类型检查它呢?===typeof

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

评论

0赞 Simon East 6/29/2011
埃里克说得好。检查类型是否也会影响性能?
6赞 Antony Hatchkins 12/18/2011
@Simon:恰恰相反 - 在“===”情况下,避免胁迫可能会对性能造成轻微影响。快速和肮脏的测试表明,在FF5.0.1下,“===”比“==”快5%
6赞 Antony Hatchkins 12/18/2011
更彻底的测试表明,在 FF、IE 和 Chrome 下,“==”或多或少比“===”(5-10%)快,而 Opera 根本没有任何区别:jsperf.com/triple-equals-vs-twice-equals/6
4赞 Alnitak 8/13/2012
使用 still 至少需要类型检查 - 解释器在不知道两个操作数的类型之前无法比较它们。==
8赞 svidgen 6/28/2013
==比:)少一个字符===
75赞 Michael Anderson 6/8/2011 #8

问题归结为三种情况:

  1. 该对象具有属性,但其值不是 。undefined
  2. 该对象具有属性,其值为 。undefined
  3. 该对象没有该属性。

这告诉我们一些我认为很重要的事情:

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

但不幸的是,他没有告诉我们我们有三种情况中的哪一种。但是,我们可以将其与情况结合起来以区分情况。typeof obj.foo"foo" in obj

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

值得注意的是,这些测试对于参赛作品也是一样的null

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

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

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

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

在没有检查未定义的情况下编写时,这更清晰。

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

但如前所述,这些并不完全相同(但足以满足我的需求)。

评论

10赞 Simon East 6/15/2011
嗨,迈克尔。很好的建议,我认为它确实让事情变得更干净。然而,我发现的一个问题是,当使用 !带有“in”的运算符。你必须说在里面用括号括起来,因为 !运算符优先于“in”。希望对某人有所帮助。if (!("x" in blob)) {}
0赞 tex 2/25/2012
对不起,迈克尔,但鉴于最初的问题,这是不正确的,或者至少是误导性的。'in' 不足以测试对象属性是否具有 typeof undefined。为了证明这一点,请看这个小提琴:jsfiddle.net/CsLKJ/4
2赞 mgol 9/27/2012
这两个代码部分执行不同的事情!考虑和反对 ;然后 but 和 .a = {b: undefined}typeof a.b === typeof a.c === 'undefined''b' in a!('c' in a)
3赞 RobG 4/1/2014
+1.OP 没有明确属性是否存在并且值是否未定义,或者属性本身是否未定义(即不存在)。
0赞 mucaho 5/15/2015
我建议将您第一个表中的点 (2.) 更改为或至少将其添加为表中 (2.) 的另一个替代方案 - 我不得不思考一会儿才能意识到 (2.) 的计算结果(尽管您稍后提到)。{ x : undefined }undefined
21赞 Codebeat 8/12/2011 #9

如果你这样做

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

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

由于窗口对象在函数外部具有全局作用域(默认对象),因此声明将“附加”到 window 对象。

例如:

var myvar = 'test';

全局变量 myvar 与 window.myvarwindow['myvar'] 相同

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

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

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

当您需要特定类型时,请测试变量的类型。为了加快测试条件的速度,您最好执行以下操作:

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

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

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

(一)

10赞 Anoop 10/17/2011 #10

您可以使用以下代码获取一个带有路径的 all undefined 数组。

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

jsFiddle 链接

评论

0赞 icktoofay 5/14/2013
虽然它不会影响代码的有效性,但你有一个错别字:应该是 .getUndefiendgetUndefined
31赞 Joe Johnson 9/26/2012 #11

我没有看到(希望我没有错过)任何人在酒店之前检查对象。因此,这是最短和最有效的(尽管不一定是最清楚的):

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

如果 obj 或 obj.prop 为 undefined、null 或 “falsy”,则 if 语句将不会执行代码块。这通常是大多数代码块语句(在 JavaScript 中)中所需的行为。

更新: (2021/7/2)

最新版本的 JavaScript 引入了一个新的运算符 可选链接:?.

这可能是检查对象属性是否存在的最明确和最有效的方法。

编号: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining

评论

2赞 mb21 2/5/2013
如果你想知道为什么这样做: Javascript:逻辑运算符和真实/虚假
0赞 Stijn de Witt 11/1/2015
如果要将属性分配给变量(如果已定义),而不是 null 和 falsey,则使用一些默认值,可以使用:var x = obj && obj.prop || 'default';
0赞 NikoKyriakid 7/20/2018
我认为问题在于明确检查未定义。根据JS的所有错误值检查条件。
0赞 Seth 4/29/2022
不要这样做,如果 是 、 和其他各种虚假值,它将失败。这正是我们不应该做的,也适用于可选链接,不应该以这种方式使用。obj.propfalse0""
27赞 drzaus 1/14/2013 #12

交叉发布我从相关问题中的答案 如何在 JavaScript 中检查“未定义”?

具体到这个问题,请参阅 someObject.<whatever> 的测试用例。


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

(请注意,测试中使用 var for 在作用域包装器中会有所不同)

参考代码:

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

结果:

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
137赞 Konstantin Smolyanin 8/9/2013 #13

这是什么意思:“未定义的对象属性”

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

var o = { a: undefined }

未定义?是的!其值未定义。未定义?确定!根本没有属性“b”!好了,现在看看不同的方法在这两种情况下的行为:o.ao.b

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)你想知道一个属性是未被第一或第二含义定义的(最典型的情况)。

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

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

'prop' in obj

笔记:

  • 不能同时检查对象及其属性。例如,如果未定义 x,则会引发 this 或 this。x.a === undefinedtypeof x.a == 'undefined'ReferenceError: x is not defined
  • 变量是一个全局变量(所以实际上它在浏览器中)。自 ECMAScript 第 1 版以来,它一直受到支持,并且从 ECMAScript 5 开始,它是只读的。因此,在现代浏览器中,它不能像许多作者喜欢吓唬我们的那样被重新定义为真实,但对于旧浏览器来说仍然如此。undefinedwindow.undefined

最后一战:对obj.prop === undefinedtypeof obj.prop == 'undefined'

优点:obj.prop === undefined

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

缺点:obj.prop === undefined

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

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

  • 它真的很普遍!它适用于新旧浏览器。

缺点:typeof obj.prop == 'undefined'

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

更新(适用于服务器端 JavaScript):

Node.js 支持全局变量 as(也可以在没有“全局”前缀的情况下使用)。我不知道服务器端 JavaScript 的其他实现。undefinedglobal.undefined

评论

0赞 Konstantin Smolyanin 9/11/2013
@Bergi感谢您的评论。我已经纠正了我的答案。在我的辩护中,我可以说目前(截至 v.0.10.18)官方 Node.js 文档没有提到作为 .此外,既不显示也不显示未定义全局成员。但测试显示相反。undefinedglobalconsole.log(global);for (var key in global) { ... }'undefined' in global
4赞 Bergi 9/11/2013
它不需要额外的文档,因为它在 EcmaScript 规范中,这也说这是错误的:-)[[Enumerable]]
5赞 hlovdal 10/24/2014
关于 ,这可以通过写成 来避免。这也给出了非常好的对称性。Minuses of typeof obj.prop == 'undefined'typeof obj.prop == typeof undefined
3赞 Ry- 4/12/2018
@hlovdal:这完全没有意义。obj.prop === undefined
2赞 Frank N 6/11/2018
当我们忠于问题标题“检测未定义的属性”时,而不是忠于第一句话中的(不同且容易得多的)问题(“检查是否未定义...”),您回答)...你的答案确实是这里的第一个正确答案。几乎所有其他人都只是回答这句话。if ('foo' in o
8赞 wayneseymour 8/15/2013 #14

这是我的情况:

我正在使用 REST 调用的结果。结果应从 JSON 解析为 JavaScript 对象。

我需要为一个错误辩护。如果 REST 调用的参数不正确,因为用户指定参数错误,则 REST 调用基本上为空。

在使用这篇文章来帮助我防御这个问题时,我尝试了这个:

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

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

我要说的是,就我的情况而言,这篇文章中之前的所有建议都不起作用。我不是说我是对的,每个人都是错的。我根本不是JavaScript大师,但希望这会对某人有所帮助。

评论

0赞 12/18/2017
你的警卫实际上并不能防范任何直接比较无法处理的事情。如果未定义或未声明,它仍会引发。typeofrestResult
0赞 Headbank 2/28/2019
在你的例子中,你可以更简单地检查数组是否为空:if(!restResult.data.length) { throw "Some error"; }
15赞 Marthijn 12/19/2013 #15

在文章《探索JavaScript中Null和Undefined的深渊》中,我读到像Underscore.js这样的框架使用这个函数:

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

评论

3赞 RobG 4/1/2014
void 0只是一种简短的书写方式(因为这是 void 后跟任何表达式返回的内容),它可以节省 3 个字符。它也可以,但这是另一个字符。:-)undefinedvar a; return obj === a;
2赞 Brian M. Hunt 9/14/2015
void是一个保留字,而不是 即 while 默认等于 ,您可以为 e.g. 赋值。undefinedundefinedvoid 0undefinedundefined = 1234
0赞 Stijn de Witt 11/1/2015
isUndefined(obj): 16 个字符 : 14 个字符 'Nough 说。obj === void 0
10赞 bevacqua 1/2/2014 #16

与 相比,简洁起见。void 0

if (foo !== void 0)

它没有那么冗长if (typeof foo !== 'undefined')

评论

3赞 daniel1426 3/8/2014
但是,如果未声明,它将抛出 ReferenceError。foo
1赞 12/18/2017
@daniel1426:所以如果你的代码中有一个错误,你想隐藏它而不是修复它?这不是一个好方法,IMO。
0赞 gaperton 10/4/2018
这不用于隐藏错误。这是检测环境属性以定义 polyfill 的常用方法。例如: if( typeof Promise === 'undefined' ){ /* 定义 Promise */ }
13赞 DenisS 2/11/2014 #17

'if (window.x) { }' 是安全的

你很可能想要.即使 x 尚未声明 () - 浏览器不会抛出错误,此检查也是安全的。if (window.x)var x;

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

if (window.history) {
    history.call_some_function();
}

工作原理:

window 是一个对象,它把所有全局变量都作为其成员,尝试访问不存在的成员是合法的。如果 x 尚未声明或尚未设置,则返回 undefined。当 if() 计算它时,undefined 会导致 falsewindow.x

评论

0赞 Stijn de Witt 11/1/2015
但是,如果您在 Node 中运行呢? 实际上在这两个系统中都有效。typeof history != 'undefined'
285赞 Ry- 2/27/2014 #18

这里的许多答案都强烈推荐,但这是一个糟糕的选择。它永远不应该用于检查变量是否具有值,因为它充当了值和变量是否存在的组合检查。在绝大多数情况下,您知道变量何时存在,如果您在变量名称或字符串文字中输入错别字,则只会引入静默失败的可能性。typeoftypeofundefinedundefinedtypeof'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!
}

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

var foo = …;

if (foo === undefined) {
    ⋮
}

对此的一些常见误解包括:

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

  • 可以被覆盖。确实,这不是一个关键字,但它只读且不可配置的。尽管它们处于非关键字状态(、、...),但您可能无法避免其他内置组件,并且实际代码通常不是在主动恶意环境中编写的,因此这不是一个值得担心的好理由。(但是,如果您正在编写代码生成器,请随意使用 。undefinedundefinedObjectMathNaNundefinedvoid 0

随着变量的工作方式的解决,是时候解决实际问题了:对象属性。没有理由对对象属性使用。前面关于特征检测的例外在这里不适用 - 仅在变量上具有特殊行为,并且引用对象属性的表达式不是变量。typeoftypeof

这:

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

始终完全等同于此³:

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

考虑到上面的建议,为了避免让读者混淆你为什么要使用 ,因为它最有意义用于检查相等性,因为它可以重构为以后检查变量的值,而且因为它看起来更好,你也应该始终在这里使用 === undefined³typeof===

当涉及到对象属性时,还需要考虑的是你是否真的要检查。给定的属性名称可以存在于对象上(读取时产生值),可以以值存在于对象本身,可以以值存在于对象的原型上,也可以存在于具有非值的对象原型上。 会告诉你一个键是否在对象的原型链上的任何位置,并告诉你它是否直接在对象上。不过,我不会在这个答案中详细介绍原型和使用对象作为字符串键控映射,因为它主要是为了反驳其他答案中的所有不良建议,而不管对原始问题的可能解释如何。阅读 MDN 上的对象原型以获取更多信息!undefinedundefinedundefinedundefinedundefined'key' in objObject.prototype.hasOwnProperty.call(obj, 'key')

¹ 示例变量名称的不寻常选择? 这是来自 Firefox 的 NoScript 扩展的真正死代码。
² 不过,不要以为不知道范围一般是可以的。 滥用动态范围导致的额外漏洞: Project Zero 1225
³ 再次假设 ES5+ 环境,undefined 指的是全局对象的 undefined 属性。

评论

1赞 CherryDT 3/18/2020
任何非默认上下文也可以覆盖 , 比如 , , 或 , 或者 ,或者默认情况下您希望在全局范围内找到的任何内容。MathObjectsetTimeout
0赞 Fuseteam 7/30/2020
ohw kay foo !== void 0 有效且更短,猜测我可以使用它:3,我知道当你评论>:D时,我指的是你自己的答案
0赞 Fuseteam 7/30/2020
现在它没有记录它做了什么,读起来可能会令人困惑,所以我会让一个函数 isDefined 返回 true if is not void 0 和 false if is and false instead >:3
0赞 Ry- 7/30/2020
@Fuseteam:使用 .实际上,我可能应该删除有关.!== undefinedvoid 0
0赞 Ry- 7/31/2020
@Fuseteam:它的可读性不强,也没有实际优势。undefined
12赞 sam 5/5/2014 #19
"propertyName" in obj //-> true | false
7赞 Juan Garcia 6/18/2014 #20

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

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

例:

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

太糟糕了,这是正确的答案,却被错误的答案所掩盖 >_<

所以,对于任何路过的人,我会免费给你未定义的!!

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
6赞 Angelin Nadar 7/8/2014 #21

浏览注释,对于那些想要检查它是否未定义或其值为 null 的人来说:

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

如果您使用的是jQuery库,那么对于这两种情况都足够了,jQuery.isEmptyObject()

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;

评论

0赞 Henry Heleine 12/10/2014
jQuery还将处理不同JavaScript API的任何跨浏览器兼容性问题。
4赞 Seti 10/9/2014 #22

我想向你展示我正在使用的东西来保护变量:undefined

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

这禁止任何人更改该值,从而销毁基于该变量的代码。如果使用 ,任何试图更改其值的内容都将以错误告终,否则它将被静默忽略。window.undefined"use strict"

6赞 Vitalii Fedorenko 12/15/2014 #23

如果您使用的是 Angular:

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

下划线 .js:

_.isUndefined(obj) 
_.isUndefined(obj.prop) 

评论

2赞 Stijn de Witt 11/1/2015
如何添加到变量?我需要下划线还是jQuery?(令人惊讶的是,人们甚至会使用库进行最基本的操作,例如检查)1xtypeof
13赞 Travis 2/15/2015 #24

读完这篇文章,我很惊讶我没有看到这个。我找到了多种算法可以做到这一点。

从未定义

如果从未定义过对象的值,则在将其定义为 或 时,这将阻止返回。如果您希望为设置为truenullundefinedundefined

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

定义为未定义或从未定义

如果希望它的结果与使用 的值 定义的值相同,或者从未定义,则只需使用trueundefined=== undefined

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

定义为虚假值、undefined、null 或 never defined。

通常,人们会要求我提供一种算法来确定一个值是假的,还是 .以下有效。undefinednull

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

评论

4赞 Stijn de Witt 11/1/2015
我认为您可以将最后一个示例替换为if (!obj.prop)
0赞 Travis 4/7/2017
@StijndeWitt,你可以,我写这篇文章的时候很没有经验,我的英语似乎同样糟糕,但是,答案中没有任何错误
3赞 Patrick Roberts 6/16/2017
var obj = {foo: undefined}; obj.foo === void 0 -> true.“从未被定义为”是怎么回事?这是错误的。undefined
0赞 Travis 5/15/2020
@PatrickRoberts 你是对的。当我在 2015 年 2 月(在 ES6 之前)写下这个答案时,我概述的第一个选项确实有效,但现在已经过时了。
5赞 Val 3/6/2015 #25

我用来测试它是否被定义。一个简单的,在之前的答案中推荐,对我来说失败了。if (this.variable)if (variable)

事实证明,它仅在变量是某个对象的字段时才起作用,以检查它是否在字典中定义。但是我们可以使用 or 作为字典对象,因为据我所知,任何变量都是当前窗口中的字段。因此,这里有一个测试:obj.someFieldthiswindow

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

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

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

9赞 Marian Klühspies 3/3/2016 #26

有一种漂亮而优雅的方法可以将定义的属性分配给新变量(如果已定义)或为其分配默认值作为回退(如果未定义)。

var a = obj.prop || defaultValue;

如果您有一个函数,该函数接收其他配置属性,则适合:

var yourFunction = function(config){

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

现在执行

yourFunction({yourConfigValue:2});
//=> 2

yourFunction();
//=> 1

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

评论

0赞 konieckropka 3/4/2022
使用 ||(OR) 将使用类型强制将“undefined”和“null”值设置为 false,将所有其他值用于“true”。------- 如果选中的属性(例如“obj.prop”和“config”)未定义或为空,则将为其分配“默认值”。在任何其他情况下,该值都不会更改。-------- 此 soultion 不检查对象是否定义了 HAS 属性。------------------------------------------------ 要检查对象是否具有属性,可以使用:let objAndPropCheck = (obj || { }).prop || 0;
15赞 Alireza 5/24/2017 #27

简单地说,任何事物都没有在 JavaScript 中定义,是未定义的,无论是对象/数组中的属性还是只是一个简单的变量......

JavaScript 可以很容易地检测未定义的变量。typeof

只需检查是否,它将返回一个布尔值。typeof whatever === 'undefined'

这就是 AngularJs v.1x 中著名的函数的编写方式:isUndefined()

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

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

因此,让我们看一下传递值时的结果,包括如下所示的对象属性,这是我们拥有的变量列表:

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

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

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

正如你所看到的,我们可以在代码中使用这样的东西来检查任何东西,如前所述,你可以简单地在你的代码中使用,但如果你一遍又一遍地使用它,创建一个像我分享的 angular 示例一样的函数,并按照以下 DRY 代码模式继续重用。typeof

还有一件事,要检查实际应用程序中对象的属性,甚至不确定对象是否存在,请先检查对象是否存在。

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

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

如此简单,您可以包装在 if 语句中,如下所示:

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

这也等于 Angular 1.x 中的 isDefined...

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

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

我还从 MDN 中添加了这一部分,其中包含有关 typeof、undefined 和 void(0) 的有用信息。

严格相等和未定义
您可以使用 undefined 和严格相等和不等式运算符来确定变量是否具有 一个值。在下面的代码中,未定义变量 x,并且 if 语句的计算结果为 true。

var x;
if (x === undefined) {
   // these statements execute
}
else {
   // these statements do not execute
}

注意:严格相等运算符,而不是标准相等 这里必须使用运算符,因为 x == undefined 还会检查是否 x 为 null,而严格相等则不为空。null 不等同于 定义。有关详细信息,请参阅比较运算符。


typeof 运算符和 undefined
或者,可以使用 typeof:

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

使用 typeof 的一个原因是,如果 变量尚未声明。

// x has not been declared before
if (typeof x === 'undefined') { // evaluates to true without errors
   // these statements execute
}

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

}

但是,应避免使用这种技术。JavaScript 是一个 静态作用域语言,因此知道变量是否被声明可以 通过查看它是否在封闭上下文中声明来阅读。这 唯一的例外是全局作用域,但全局作用域绑定到 全局对象,因此检查 全局上下文可以通过检查 全局对象(例如,使用 in 运算符)。


Void 运算符和 undefined

void 运算符是第三种选择。

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

更多>在这里

6赞 blackmiaool 10/28/2017 #28

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

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:

尝试获取输入值的属性,并检查错误消息是否存在。如果输入值未定义,则错误消息将为 Uncaught TypeError: Cannot read property 'b' of undefined

isUndefined2:

将输入值转换为要比较的字符串,并确保其为负值。"undefined"

isUndefined3:

在 JavaScript 中,当输入值完全为 时,可选参数起作用。undefined

16赞 Przemek Struciński 9/27/2019 #29

ECMAScript 10 引入了一个新特性 - 可选链接,仅当对象定义如下时,才可以使用它来使用对象的属性:

const userPhone = user?.contactDetails?.phone;

仅当定义了 user 和 contactDetails 时,它才会引用 phone 属性。

编号 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining

评论

0赞 Al Hill 6/6/2020
我曾经使用过很多从 lodash 获取的功能,非常方便访问此类对象,但是新的可选链接涵盖了 _.get 的大部分用途
0赞 Ben Racicot 3/23/2022
这是问题的答案。
7赞 S.Saderi 5/5/2020 #30

有一种非常简单易行的方法。

您可以使用可选链接

x = {prop:{name:"sajad"}}

console.log(x.prop?.name) // Output is: "sajad"
console.log(x.prop?.lastName) // Output is: undefined

if(x.prop?.lastName) // The result of this 'if' statement is false and is not throwing an error

甚至可以对函数或数组使用可选链接。

截至 2020 年年中,这尚未普遍实施。查看文档 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining