如何检查JavaScript中的对象属性是否未定义?
当前回答
检查属性值是否为未定义的特殊值的通常方法是:
if(o.myProperty === undefined) {
alert("myProperty value is the special value `undefined`");
}
要检查对象是否实际上没有这样的属性,并且当您尝试访问它时,默认情况下会返回undefined:
if(!o.hasOwnProperty('myProperty')) {
alert("myProperty does not exist");
}
要检查与标识符关联的值是否为未定义的特殊值,或者该标识符是否尚未声明:
if(typeof myVariable === 'undefined') {
alert('myVariable is either the special value `undefined`, or it has not been declared');
}
注意:最后一个方法是引用未声明的标识符而不出现早期错误的唯一方法,这与值为undefined不同。
在ECMAScript 5之前的JavaScript版本中,全局对象上名为“undefined”的属性是可写的,因此,如果不小心重新定义了foo==undefineed,则简单的检查可能会出现意外的行为。在现代JavaScript中,属性是只读的。
然而,在现代JavaScript中,“undefined”不是关键字,因此函数内部的变量可以命名为“undefine”,并隐藏全局属性。
如果您担心这种(不太可能的)边缘情况,可以使用void运算符获取特殊的未定义值本身:
if(myVariable === void 0) {
alert("myVariable is the special value `undefined`");
}
其他回答
交叉发布我对相关问题的回答如何在JavaScript中检查“undefined”?。
具体到这个问题,请参阅someObject的测试用例<无论什么>。
说明各种答案结果的一些场景:http://jsfiddle.net/drzaus/UVjM4/
(请注意,在测试中使用var会在作用域包装器中产生差异)
参考代码:
(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
来自lodash.js。
var undefined;
function isUndefined(value) {
return value === undefined;
}
它创建了一个名为undefined的局部变量,该变量用默认值(即真正的undefineed)初始化,然后将该值与变量undefine进行比较。
更新日期:2019年9月9日
我发现Lodash更新了它的实现。查看我的问题和代码。
要做到防弹,只需使用:
function isUndefined(value) {
return value === void 0;
}
在《探索JavaScript中的空和未定义的深渊》一文中,我看到Undercore.js等框架使用了这个函数:
function isUndefined(obj){
return obj === void 0;
}
这可能是确定现有属性名称是否具有显式和预期值undefined的唯一显式形式;尽管如此,这是一种JavaScript类型。
"propertyName" in containerObject && ""+containerObject["propertyName"] == "undefined";
>> true \ false
仅当给定上下文的属性名存在(真实存在)并且其预期值未明确定义时,此表达式才会返回true。
不会出现假阳性,例如空字符串、空字符串、零、空数组等。这正是如此。检查,即确保属性名存在(否则将为假阳性),然后显式检查其值是否未定义,例如其字符串表示形式中的未定义JavaScript类型(字面上为“undefined”),因此==而不是==,因为无法进行进一步转换。只有满足这两个条件,这个表达式才会返回true。例如,如果属性名称不存在,则返回false。这是唯一正确的返回,因为不存在的财产不能有值,甚至不能有未定义的值。
例子:
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
"propertyName" in obj //-> true | false