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


当前回答

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

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

其他回答

查看注释,对于那些想同时检查两者的人来说,它是未定义的还是其值为空:

//Just in JavaScript
var s; // Undefined
if (typeof s == "undefined" || s === null){
    alert('either it is undefined or value is null')
}

如果您使用的是jQueryLibrary,那么jQuery.isEmptyObject()将足以满足这两种情况,

var s; // Undefined
jQuery.isEmptyObject(s); // Will return true;

s = null; // Defined as null
jQuery.isEmptyObject(s); // Will return true;

//Usage
if (jQuery.isEmptyObject(s)) {
    alert('Either variable:s is undefined or its value is null');
} else {
     alert('variable:s has value ' + s);
}

s = 'something'; // Defined with some value
jQuery.isEmptyObject(s); // Will return false;

在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测试更具特异性。如果您需要知道对象属性是用undefined初始化的还是从未初始化过,请使用Object.getOwnPropertyDescriptor():

// to test someObject.someProperty
var descriptor = Object.getOwnPropertyDescriptor(someObject, 'someProperty');

if (typeof descriptor === 'undefined') {
  // was never initialized
} else if (typeof descriptor.value === 'undefined') {
  if (descriptor.get || descriptor.set) {
    // is an accessor property, defined via getter and setter
  } else {
    // is initialized with `undefined`
  }
} else {
  // is initialized with some other value
}

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

检查属性值是否为未定义的特殊值的通常方法是:

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`");
}