如何检查JavaScript中的对象属性是否未定义?
当前回答
问题归结为三种情况:
对象具有属性,其值未定义。对象具有属性,其值未定义。对象没有属性。
这告诉了我们一些我认为重要的事情:
未定义成员和具有未定义值的已定义成员之间存在差异。
但不幸的是,obj.foo的类型并不能告诉我们这三种情况中的哪一种。然而,我们可以将其与obj中的“foo”结合起来,以区分情况。
| typeof obj.x === 'undefined' | !("x" in obj)
1. { x:1 } | false | false
2. { x : (function(){})() } | true | false
3. {} | true | true
值得注意的是,这些测试对于空条目也是相同的
| 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); }
但正如前面提到的,这些并不完全相同(但已经足够满足我的需求)。
其他回答
Object.hasOwnProperty(o,'propertyname');
然而,这并不能通过原型链进行查找。
在ECMAScript 6中引入,我们现在可以使用代理以一种新的方式处理未定义。它可以用于为任何不存在的财产设置默认值,这样我们就不必每次都检查它是否实际存在。
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)
将输出以下文本而不会得到任何未定义。
Name: Kevin , Age: N/A , Gender: N/A
我不确定将==与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
Lodash库中有几个小助手:
isUndefined-检查值是否未定义。
_.isUndefined(undefined) // => true
_.isUndefined(null) // => false
has-检查对象是否包含属性
const object = { 'a': { 'b': 2 } }
_.has(object, 'a.b') // => true
_.has(object, 'a.c') // => false
我认为这个问题有很多不正确的答案。与通常的看法相反,“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的情况下引发错误。