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


当前回答

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

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

var o = { a: undefined }

o.a是否未定义?对其值未定义。是否未定义o.b?当然根本没有属性“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

我们可以清楚地看到,obj.prop==“undefined”和obj.prop==undefineed的类型是等价的,它们不能区分这些不同的情况。obj中的“prop”可以检测属性根本没有定义并且没有注意可能未定义的属性值的情况。

那该怎么办?

1) 您想知道一个属性是由第一个含义还是第二个含义定义的(最典型的情况)。

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

2) 您只想知道对象是否具有某些属性,而不关心其值。

'prop' in obj

笔记:

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

最后一战:obj.prop==未定义vs obj.prop类型==“未定义”

obj.prop的加号==未定义:

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

obj.prop的最小值==未定义:

在旧浏览器中可以重写undefined

obj.prop类型的加号==“undefined”:

它真的很普遍!它可以在新旧浏览器中使用。

obj.prop类型的最小值==“undefined”:

这里的“undefined”(拼写错误)只是一个字符串常量,因此如果您像我刚才那样拼写错误,JavaScript引擎将无法帮助您。

更新(针对服务器端JavaScript):

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

其他回答

在《探索JavaScript中的空和未定义的深渊》一文中,我看到Undercore.js等框架使用了这个函数:

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

我不确定将==与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

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

事实证明,只有当变量是某个对象obj.someField的字段时,它才能工作,以检查它是否在字典中定义。但我们可以使用this或window作为字典对象,因为任何变量都是当前窗口中的字段,正如我所理解的那样。因此,这里有一个测试:

如果(this.abc)警报(“已定义”);其他的警报(“未定义”);abc=“abc”;如果(this.abc)警报(“已定义”);其他的警报(“未定义”);

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

这可能是确定现有属性名称是否具有显式和预期值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

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

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