如何检查JavaScript中的对象属性是否未定义?
当前回答
function isUnset(inp) {
return (typeof inp === 'undefined')
}
如果变量已设置,则返回false;如果未定义,则返回true。
然后使用:
if (isUnset(var)) {
// initialize variable here
}
其他回答
这里的许多答案都强烈推荐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指的是全局对象的未定义属性。
我认为这个问题有很多不正确的答案。与通常的看法相反,“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==undefined将在未声明myVar的情况下引发错误。
解决方案不正确。在JavaScript中,
null == undefined
将返回true,因为它们都“强制”为布尔值,并且都为false。正确的方法是检查
if (something === undefined)
这是身份运算符。。。
Lodash库中有几个小助手:
isUndefined-检查值是否未定义。
_.isUndefined(undefined) // => true
_.isUndefined(null) // => false
has-检查对象是否包含属性
const object = { 'a': { 'b': 2 } }
_.has(object, 'a.b') // => true
_.has(object, 'a.c') // => false
Object.hasOwnProperty(o,'propertyname');
然而,这并不能通过原型链进行查找。