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

考虑:

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

这是最好的方法吗?


当前回答

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

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开始,这是安全的。

其他回答

考虑Javascript中的以下对象

const x = {key: 1};

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

console.log("key" in x);

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

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

您必须考虑此对象属性是否可枚举,因为非可枚举财产不会显示在for-in循环中。此外,如果可枚举属性隐藏了原型的不可枚举属性,它将不会在InternetExplorer8和更早版本中显示。

如果您想要所有实例财产的列表,无论是否可枚举,您可以使用

Object.getOwnPropertyNames(x);

这将返回对象上存在的所有财产的名称数组。

反射提供了可用于与Javascript对象交互的方法。静态Reflect.has()方法的工作方式类似于函数中的in运算符。

console.log(Reflect.has(x, 'key'));
// expected output: true

console.log(Reflect.has(x, 'key2'));
// expected output: false

console.log(Reflect.has(object1, 'toString'));
// expected output: true

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

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

如果对象上不存在该属性,它将返回字符串undefined。否则,它将返回适当的属性类型。但是,请注意,这并不总是检查对象是否具有属性的有效方法,因为您可以将属性设置为undefined,在这种情况下,使用typeof x.key仍将返回true(即使该键仍在对象中)。

类似地,您可以通过直接与未定义的Javascript属性进行比较来检查属性是否存在

if (x.key === undefined) {
    console.log("undefined");
}

除非在x对象上特别将key设置为undefined,否则这应该有效

迭代对象自身财产的更好方法:

如果要在不使用hasOwnProperty()检查的情况下迭代对象的财产,用于(let key of Object.keys(stud)){}方法:

for(let key of Object.keys(stud)){
  console.log(key); // will only log object's Own properties
}

完整示例并与hasOwnProperty()中的for进行比较

function Student() {
  this.name = "nitin";
}

Student.prototype = {
  grade: 'A'
}

let stud = new Student();

// for-in approach
for(let key in stud){
  if(stud.hasOwnProperty(key)){
    console.log(key); // only outputs "name"
  }
} 

//Object.keys() approach
for(let key of Object.keys(stud)){
  console.log(key);
}

对于测试简单对象,请使用:

if (obj[x] !== undefined)

如果您不知道它是什么对象类型,请使用:

if (obj.hasOwnProperty(x))

所有其他选项都较慢。。。

细节

对Node.js下100000000个周期的性能评估,其他人在这里建议了五个选项:

function hasKey1(k,o) { return (x in obj); }
function hasKey2(k,o) { return (obj[x]); }
function hasKey3(k,o) { return (obj[x] !== undefined); }
function hasKey4(k,o) { return (typeof(obj[x]) !== 'undefined'); }
function hasKey5(k,o) { return (obj.hasOwnProperty(x)); }

评估告诉我们,除非我们特别想检查对象的原型链以及对象本身,否则不应使用通用形式:

if (X in Obj)...

根据使用情况,速度慢2到6倍

hasKey1 execution time: 4.51 s
hasKey2 execution time: 0.90 s
hasKey3 execution time: 0.76 s
hasKey4 execution time: 0.93 s
hasKey5 execution time: 2.15 s

总之,如果您的Obj不一定是一个简单的对象,并且您希望避免检查对象的原型链,并确保x由Obj直接拥有,请使用if(Obj.hasOwnProperty(x))。。。。

否则,当使用简单对象而不担心对象的原型链时,使用if(typeof(obj[x])!=='undefined')。。。是最安全、最快的方式。

如果你使用一个简单的对象作为哈希表,并且从不做任何奇怪的事情,我会使用If(obj[x])。。。因为我觉得它更可读。

对象上存在一个方法“hasOwnProperty”,但不建议直接调用此方法,因为有时可能是对象为空或对象上存在某些属性,例如:{hasOwnProperty:false}

因此,更好的方法是:

//好的var obj={“bar”:“here bar desc”}console.log(Object.pr原型.hasOwnProperty.call(obj,“bar”));//最佳const has=Object.prototype.hasOwnProperty;//在模块范围内缓存查找一次。console.log(has.call(obj,“bar”));

现在使用ECMAScript22,我们可以使用hasOwn而不是hasOwnProperty(因为这个特性有缺陷)

Object.hasOwn(obj, propKey)