如何检查JavaScript中的对象属性是否未定义?
当前回答
来自lodash.js。
var undefined;
function isUndefined(value) {
return value === undefined;
}
它创建了一个名为undefined的局部变量,该变量用默认值(即真正的undefineed)初始化,然后将该值与变量undefine进行比较。
更新日期:2019年9月9日
我发现Lodash更新了它的实现。查看我的问题和代码。
要做到防弹,只需使用:
function isUndefined(value) {
return value === void 0;
}
其他回答
检查属性值是否为未定义的特殊值的通常方法是:
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中处理未定义的7个技巧》,它展示了关于未定义的真正有趣的事情如:
undefined的存在是JavaScript的许可性质的结果,允许使用:
未初始化变量不存在的对象财产或方法访问数组元素的越界索引不返回任何内容的函数的调用结果
这里的许多答案都强烈推荐typeof,但typeof是一个糟糕的选择。它不应用于检查变量是否具有未定义的值,因为它充当了未定义值和变量是否存在的组合检查。在绝大多数情况下,您知道变量何时存在,如果您在变量名称或字符串文字“undefined”中键入了错误,typeof可能会导致无声失败。
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!
}
因此,除非您正在进行功能检测²,否则给定名称是否在范围内存在不确定性(例如检查typeof module!=='undefined'作为CommonJS环境特定代码的一个步骤),否则在变量上使用typeof是一个有害的选择,正确的选择是直接比较值:
var foo = …;
if (foo === undefined) {
⋮
}
对此,一些常见的误解包括:
读取“未初始化”变量(varfoo)或参数(函数栏(foo){…},称为bar())将失败。这根本不是真的——没有显式初始化的变量和没有给定值的参数总是未定义,并且总是在范围内。可以覆盖未定义的。的确,undefined不是关键字,但它是只读的,不可配置。尽管有其他内置程序的非关键字状态(Object、Math、NaN…),但您可能无法避免它们,而且实用代码通常不是在主动恶意环境中编写的,因此这不是担心未定义的好理由。(但如果您正在编写代码生成器,请随意使用void 0。)
随着变量如何发挥作用,是时候解决实际问题了:对象财产。没有理由对对象财产使用typeof。早期关于特征检测的例外在这里不适用–typeof只对变量有特殊行为,引用对象财产的表达式不是变量。
这:
if (typeof foo.bar === 'undefined') {
⋮
}
始终完全等于此³:
if (foo.bar === undefined) {
⋮
}
考虑到上面的建议,避免让读者混淆为什么要使用typeof,因为使用==来检查等式是最有意义的,因为稍后可以将其重构为检查变量的值,并且因为它看起来更简单,所以在这里也应该始终使用==undefined³。
当涉及到对象财产时,需要考虑的另一件事是您是否真的想检查未定义的属性。给定的属性名称可以在对象上不存在(读取时产生未定义的值),可以在对象本身上出现,但值未定义,可以在该对象的原型上出现,值未定义或出现在其中一个值未定义的对象上obj中的“key”将告诉您键是否位于对象原型链上的任何位置,而object.protype.hasOwnProperty.call(obj,“key”)将告诉您它是否直接位于对象上。不过,我不会在这个答案中详细讨论原型和使用对象作为字符串键映射,因为它主要是为了应对其他答案中的所有坏建议,而不管对原始问题的可能解释。阅读MDN上的对象原型了解更多信息!
¹不寻常的变量名称示例选择?这是Firefox的NoScript扩展中真正的死代码。²但是,不要认为不知道范围内的内容是可以的。滥用动态范围导致的奖金漏洞:项目零1225再次假设ES5+环境,undefined指的是全局对象的未定义属性。
解决方案不正确。在JavaScript中,
null == undefined
将返回true,因为它们都“强制”为布尔值,并且都为false。正确的方法是检查
if (something === undefined)
这是身份运算符。。。
Object.hasOwnProperty(o,'propertyname');
然而,这并不能通过原型链进行查找。