javascript - javascript如何检查一个对象有一个属性?

  显示原文与译文双语对照的内容

javascript如何检查一个对象有一个属性?

请考虑:


x = {'key': 1};
if ( x.hasOwnProperty('key') ) {
//Do this
}

这是最好的方法?

时间:

我对所给出的答案很困惑- 大多数都是完全不正确的。 当然,你可以具有未定义的object空的或者假的对象属性。 所以简单地将属性检查减少到 typeof this[property],更糟糕的是 x.key 会给你一个完全误导的结果。

这取决于你在寻找什么。 如果你想知道一个对象是否包含一个属性( 它不是来自Prototype链的某处),那么 object.hasOwnProperty 就是。 所有现代浏览器都支持它。 ( 在旧版本的Safari - 2.0.1和更老版本中都缺少它,但是浏览器的那些版本很少使用。)

如果你正在寻找的是一个对象拥有的属性是 iterable ( 当你迭代对象的属性时,它将出现在),那么执行以下操作: prop in object 将给你所需的效果。

因为使用 hasOwnProperty 可能是你想要的,并且考虑到你可能需要一个后备方法,所以我向你展示以下解决方案:


var obj = {
 a: undefined,
 b: null,
 c: false
};

//a, b, c all found
for ( var prop in obj ) {
 document.writeln("Object1:" + prop );
}

function Class(){
 this.a = undefined;
 this.b = null;
 this.c = false;
}

Class.prototype = {
 a: undefined,
 b: true,
 c: true,
 d: true,
 e: true
};

var obj2 = new Class();

//a, b, c, d, e found
for ( var prop in obj2 ) {
 document.writeln("Object2:" + prop );
}

function hasOwnProperty(obj, prop) {
 var proto = obj.__proto__ || obj.constructor.prototype;
 return (prop in obj) &&
 (!(prop in proto) || proto[prop]!== obj[prop]);
}

if ( Object.prototype.hasOwnProperty ) {
 var hasOwnProperty = function(obj, prop) {
 return obj.hasOwnProperty(prop);
 }
}

//a, b, c found in modern browsers
//b, c found in Safari 2.0.1 and older
for ( var prop in obj2 ) {
 if ( hasOwnProperty(obj2, prop) ) {
 document.writeln("Object2 w/hasOwn:" + prop );
 }
}

一个caveat,上也算一个,跨浏览器,解决方案,以 hasOwnProperty, : 它无法区分在Prototype上和实例上相同的属性,它只是假设它来自 Prototype 。 你可以根据你的情况来更宽松或者更严格地改变它,但至少这应该是有帮助的。

使用 Underscore.js 或者( 更好的 ) lodash:

 
_.has(x, 'key');

 

调用 Object.prototype.hasOwnProperty,但( 一个) 更短,( b ) 使用"对 hasOwnProperty的安全引用"( 例如 。 即使覆盖了 hasOwnProperty,它也能工作。

特别是,lodash将 _.has 定义为:


 function has(object, key) {
 return object? hasOwnProperty.call(object, key) : false;
 }
//hasOwnProperty = Object.prototype.hasOwnProperty

记住,undefined 是( 不幸的) 不中的保留字 JavaScript 。 因此,某人( 其他人,显然) 可能有重定义它,打破你的代码。

因此,更可靠的方法如下:


if (typeof(x.attribute)!== 'undefined')

另一方面,这个方法更加冗长,也更慢。 以下:

一种常见的替代方法是,以确保 undefined 实际上 是未定义的,比如 通过将代码放入一个函数中,可以接受其他参数,称为 undefined 一样,没有被传递一个值。 为了确保没有传递值,你可以直接调用它,e.g.:


(function (undefined) {
 … your code …
 if (x.attribute!== undefined)
 … mode code …
})();

关于什么?


var x = {'key': 1};

if('key' in x){
 console.log('has');
}


if (x.key!== undefined)

Armin Ronacher 似乎已经将我的打败了,但是:


Object.prototype.hasOwnProperty = function(property) {
 return this[property]!== undefined;
};

x = {'key': 1};

if (x.hasOwnProperty('key')) {
 alert('have key!');
}

if (!x.hasOwnProperty('bar')) {
 alert('no bar!');
}

更安全,但是会降低解决方案,作为由指出Konrad RudolphArmin Ronacher 应为:


Object.prototype.hasOwnProperty = function(property) {
 return typeof this[property]!== 'undefined';
};

让我们在这里cut一些困惑。 在use,由当前的绝大多数的假定不需要推测,因为已经存在;这是真的。首先,让我们简化 browsers.

不需要推测,返回真,如果它已经被添加到属性名称,它将被传递给该对象。 它完全独立于分配给它的实际值,它可能是 undefined

因此:


var o = {}
o.x = undefined

var a = o.hasOwnProperty('x')//a is true
var b = o.x === undefined//b is also true

然而:


var o = {}

var a = o.hasOwnProperty('x')//a is now false
var b = o.x === undefined//b is still true

问题是当Prototype链中的一个对象具有未定义值的属性时,会发生什么? hasOwnProperty 对它来说是假的,所以 !== undefined 也是。 但是,for..in 仍将在枚举中列出它。

在它的Prototype chain,底线是没有 跨浏览器 ( 因为 IE 不公开 __prototype_ _ ) 方式来确定应该将特定的标识符没有被附加到一个对象或者任何东西。

可以使用 in 运算符检查对象上是否存在该属性:


x = {'key': 1};
alert("key" in x);

你还可以使用 for - in 循环循环遍历对象的所有属性,然后检查特定的属性:


for (prop in x) {
 if (prop =="key") {
//Do something
 }
}

你必须考虑这里对象属性是否可以枚举,因为non-enumerable属性不会出现在 for-in 循环中。 此外,如果可以枚举属性隐藏Prototype的non-enumerable属性,它将不会出现在 IE 8 和更早版本中。

如果你想要所有实例属性的列表,不管是否可以枚举,你都可以使用


Object.getOwnPropertyNames(x);

这将返回一个对象上所有属性的名称数组。

最后,可以使用typeof运算符直接检查对象属性的数据类型:


if (typeof x.key =="undefined") {
 alert("undefined");
}

如果对象上不存在该属性,它将返回未定义的字符串。 否则它将返回适当的属性类型。 但是,请注意,这并不是检查对象是否具有属性的有效方法,因为你可以有一个属性设置为未定义的,在这种情况下,使用 typeof x.key 仍然是 return true 。

如果你正在搜索一个属性,那么"没有"。 你需要:


if ('prop' in obj) { }

通常,你不应该关心该属性来自Prototype还是对象。

但是,因为你在示例代码中使用了'密钥',它看起来像是一个散列,在这种情况下,你的答案会有意义。 所有散列键都是对象中的属性,你可以避免Prototype所提供的额外属性。

Resig的回答非常全面,但我认为它不清晰。 特别是使用"'prop'在对象中"时。

是的,我想你也可以 Object.prototype.hasOwnProperty.call(x, 'key') 如果 x 有一个名为 hasOwnProperty的属性,它也应该工作:)

但是测试本身的属性。 如果你想检查它是否有可能也是inhered的属性,你可以使用 typeof x.foo!= 'undefined'


if (typeof x.key!="undefined") {

}

因为

 
if (x.key)

 

如果 x.key 解析为 false ( 例如 x.key ="" ),则失败。

...