如何在JavaScript中检查对象是否具有特定属性?

1818

如何在JavaScript中检查对象是否具有特定属性?

考虑以下代码:

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

那是最好的做法吗?


31
我写了一个 jsperf 测试,用大家的答案来看哪个最快:http://jsperf.com/dictionary-contains-key - styfle
('propertyName' in Object) ? '属性存在' : '属性不存在' - Mohan Ram
2
@styfle 感谢你提供的jsperf测试。对我来说,“in”和“hasOwnProperty”的速度比其他方法慢得多(慢了98%)。我对“hasOwnProperty”较慢并不感到惊讶,但我对“in”较慢感到惊讶。 - evanrmurphy
3
有一个新的第三阶段提案,Object.hasOwn,它解决了Object.prototype.hasOwnProperty的一些问题。 - Sebastian Simon
32个回答

18
if(x.hasOwnProperty("key")){
  // …
}

因为

if(x.key){
  // …
}

如果x.key为假值(例如,x.key === ""),则失败。


17

不要这样做 object.hasOwnProperty(key))。这样做非常糟糕,因为这些方法可能会被对象中的属性屏蔽 - 考虑 { hasOwnProperty: false } - 或者对象可能是一个空对象 (Object.create(null))

最好的方法是使用 Object.prototype.hasOwnProperty.call(object, key) 或者:

const has = Object.prototype.hasOwnProperty; // Cache the lookup once, in module scope.
console.log(has.call(object, key));
/* Or */
import has from 'has'; // https://www.npmjs.com/package/has
console.log(has(object, key));

6
我同意这种方法,并且认为它应该是被接受的答案,因为它是在保持性能的同时最安全的方式!https://eslint.org/docs/rules/no-prototype-builtins 表示:“例如,一个 web 服务器从客户端解析 JSON 输入并直接在生成的对象上调用 hasOwnProperty 是不安全的,因为恶意客户端可能发送一个如 {"hasOwnProperty": 1} 的 JSON 值,导致服务器崩溃。” - Arman

17

您还可以使用ES6中的Reflect对象

x = {'key': 1};
Reflect.has( x, 'key'); // returns true

这里提供了有关Reflect.has的MDN文档。

Reflect.has()是一个静态方法,作用类似于in运算符作为函数使用。


13

好的,看起来我的答案是正确的,除非你不想要继承的属性:

if (x.hasOwnProperty('key'))

以下是包含继承属性的其他选项:

if (x.key) // Quick and dirty, but it does the same thing as below.

if (x.key !== undefined)

4
警告:即使 x.key !== undefined 不成立,x.hasOwnProperty('key') 可能是真的。 - AnthonyWJones
5
对于 var x = { key: false };x.key 方法是不正确的。 - Mark K Cowan
2
如果(x.key)不正确,因为如果 x = {key:0},它将无法通过检查。 - someUser

10

另一个相对简单的方法是使用Object.keys。这将返回一个array,这意味着您可以获得数组的所有功能。

var noInfo = {};
var info = {something: 'data'};

Object.keys(noInfo).length //returns 0 or false
Object.keys(info).length //returns 1 or true

虽然我们生活在一个有很好的浏览器支持的世界,但因为这个问题非常古老,所以我想加上这一点:自JavaScript v1.8.5起,这是安全使用的。


正确,但如果您想知道info是否具有名称为someotherthing的属性呢?我认为这就是OP所寻找的。 - Victorio Berra
3
然后你会执行 Object.keys(info).indexOf('someotherthing') !== -1 - hippietrail
"JS v1.8.5"是什么?"JavaScript v1.8.5"?它似乎不符合任何ECMAScript版本(版本8于2017年发布)。 jQuery 1.8于2012年发布。 - Peter Mortensen
好的,JavaScript 1.8.5于2011年与Firefox 4(2011-03-22)一起发布。第一个版本的ECMAScript 5(链接)是从2009年开始的。 - Peter Mortensen
2
@hippietrail 我认为 Object.keys(info).includes('something') 更符合人体工程学。 - n_moen
示例在此处给出。 - majurageerthan

10

JavaScript现在正在发展和成长,因为它现在拥有良好甚至高效的检查方法。

以下是一些检查对象是否具有特定属性的简单方法:

  1. 使用hasOwnProperty()
const hero = {
  name: 'Batman'
};

hero.hasOwnProperty('name');     // => true
hero.hasOwnProperty('realName'); // => false
  1. 使用关键字/操作符in
const hero = {
  name: 'Batman'
};

'name' in hero;     // => true
'realName' in hero; // => false
  1. undefined 关键字比较
const hero = {
  name: 'Batman'
};

hero.name;     // => 'Batman'
hero.realName; // => undefined

// So consider this
hero.realName == undefined // => true (which means property does not exists in object)
hero.name == undefined // => false (which means that property exists in object)

了解更多信息,请查看此处


8

hasOwnProperty可以用来确定一个对象是否拥有指定的属性,作为该对象的直接属性;与in运算符不同,这种方法不会检查对象的原型链。

所以根据你的问题,很可能你不想使用hasOwnProperty,它只能确定属性是否直接附加在对象本身上。

如果你想确定属性是否存在于原型链中,可以像这样使用:

if (prop in object) { // Do something }

我收到了“无法使用'in'运算符在myObject中搜索'prop'”的错误信息。 - Victorio Berra

5

现在通过ECMAScript22,我们可以使用hasOwn代替hasOwnProperty(因为这个特性存在缺陷)。

Object.hasOwn(obj, propKey)

5

给定myObject对象和"myKey"作为键名:

Object.keys(myObject).includes('myKey')


myObject.hasOwnProperty('myKey')

或者
typeof myObject.myKey !== 'undefined'

最后一种方法被广泛使用,但是(正如其他答案和评论所指出的),它也可以匹配从Object原型派生的键。

5
您可以使用以下方法 -
var obj = {a:1}
console.log('a' in obj)               // 1
console.log(obj.hasOwnProperty('a'))  // 2
console.log(Boolean(obj.a))         // 3

以下方法之间的区别如下:
1. 在第一种和第三种方法中,我们不仅在对象本身中搜索,还会搜索它的原型链。如果对象本身没有该属性,但是该属性存在于其原型链中,它将返回true。

var obj = {
    a: 2,
    __proto__ : {b: 2}
}

console.log('b' in obj)
console.log(Boolean(obj.b))

第二种方法仅检查自身属性。例子 -

var obj = {
    a: 2,
    __proto__ : {b: 2}
}

console.log(obj.hasOwnProperty('b'))

  1. 第一种和第三种方法的区别在于,如果存在一个属性其值为undefined,第三种方法将会返回false,而第一种方法将会返回true。

var obj = {
    b : undefined
}

console.log(Boolean(obj.b))
console.log('b' in obj);


Boolean({b:''}.b) -> false - Kamil Kiełczewski
@KamilKiełczewski 是的,它应该返回 false,在这种情况下任何假值都将返回 false。 - Komal Bansal

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接