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

时间:2008-09-25 19:27:07

标签: javascript

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

考虑:

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

这是最好的方法吗?

32 个答案:

答案 0 :(得分:1304)

我对所给出的答案感到困惑 - 大多数答案都是完全错误的。当然,您可以拥有具有undefined,null或false值的对象属性。因此,简单地将属性检查减少到typeof this[property],或者更糟糕的是,x.key会给您带来完全误导性的结果。

这取决于你在寻找什么。如果你想知道一个对象是否物理上包含一个属性(并且它不是来自原型链上的某个地方),那么object.hasOwnProperty就是你要走的路。所有现代浏览器都支持它。 (在旧版本的Safari - 2.0.1及更早版本中缺少它 - 但这些版本的浏览器很少再使用。)

如果你正在寻找的是一个对象上有一个可迭代的属性(当你迭代对象的属性时,它会出现)然后做: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 );
    }
}

上面是hasOwnProperty的一个有效的跨浏览器解决方案,但有一点需要注意:它无法区分原型和实例上相同属性的情况 - 它只是假设它是来自原型。您可以根据自己的情况将其转移到更宽松或更严格的位置,但至少应该更有帮助。

答案 1 :(得分:261)

使用Underscore.js或(even betterlodash

_.has(x, 'key');

哪个调用Object.prototype.hasOwnProperty,但是(a)键入的时间较短,(b)使用“hasOwnProperty的安全引用”(即使覆盖hasOwnProperty它也有效)

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

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

答案 2 :(得分:115)

注意:由于严格模式和hasOwnProperty,以下现在基本上已经过时了。正确的解决方案是使用严格模式并使用obj.hasOwnProperty检查属性的存在。这个答案早于这两件事,至少广泛实施(是的,它是旧的)。请将以下内容作为历史记录。


请记住,如果您没有使用严格模式,undefined(很遗憾)是JavaScript中的保留字。因此,某人(显然是其他人)可能有重新定义它的宏伟想法,打破你的代码。

因此,更强大的方法如下:

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

另一方面,这种方法更冗长,也更慢。 : - /

一种常见的替代方法是确保undefined 实际未定义,例如将代码放入一个函数中,该函数接受一个名为undefined的附加参数,该参数未传递值。为了确保它没有传递一个值,你可以立即自己调用它,例如:

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

答案 3 :(得分:109)

怎么样?

var x = {'key': 1};

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

答案 4 :(得分:44)

if (x.key !== undefined)

Armin Ronacher似乎已经beat me to it,但是:

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!');
}

更安全但速度较慢的解决方案as pointed out Konrad RudolphArmin Ronacher将是:

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

答案 5 :(得分:34)

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

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

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

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

您必须考虑此对象属性是否可枚举,因为不可枚举的属性不会显示在for-in循环中。此外,如果可枚举属性遮蔽了原型的非可枚举属性,则它不会显示在Internet Explorer 8及更早版本中。

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

Object.getOwnPropertyNames(x);

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

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

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

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

更新:您可以通过与未定义的javascript属性进行比较来检查属性是否存在

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

除非将密钥专门设置为x对象上的undefined

,否则这应该有效

答案 6 :(得分:26)

让我们在这里解决一些困惑。首先,假设hasOwnProperty已经存在,让我们简化一下;对于当前使用的绝大多数浏览器来说都是如此。

如果传递给它的属性名称已添加到对象,则

hasOwnProperty返回true。它完全独立于分配给它的实际值,可能正好是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

问题是当原型链中的对象具有值为undefined的属性时会发生什么? hasOwnProperty将为假,!== undefined也是如此。但是,for..in仍然会在枚举中列出它。

底线是没有跨浏览器方式(因为Internet Explorer不公开__prototype__)以确定特定标识符尚未附加到对象或其原​​型链中的任何内容。

答案 7 :(得分:17)

如果您正在寻找房产,那么“否”。你想要:

if ('prop' in obj) { }

通常,您不应该关心属性是来自原型还是对象。

但是,因为您在示例代码中使用了'key',所以看起来您将对象视为哈希,在这种情况下您的答案是有意义的。所有哈希键都是对象中的属性,并且您可以避免原型提供的额外属性。

John Resig的回答非常全面,但我认为不太清楚。特别是何时在obj中使用“'prop'。”

答案 8 :(得分:13)

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

但是那可以测试自己的属性。如果您想检查它是否具有可能已被加密的属性,您可以使用typeof x.foo != 'undefined'

答案 9 :(得分:12)

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

}

由于

if (x.key)
如果x.key解析为false(例如x.key = ""),

就会失败。

答案 10 :(得分:11)

对于测试简单对象,请使用:     的 if (obj[x] !== undefined)

如果您不知道它使用的是哪种对象类型:     的 if (obj.hasOwnProperty(x))

所有其他选项都较慢..

<强>详情

Nodejs下的100,000,000个周期的性能评估到其他人建议的5个选项:

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: 4s 510.427785ms
hasKey2 execution time: 0s 904.374806ms
hasKey3 execution time: 0s 760.336193ms
hasKey4 execution time: 0s 935.19901ms
hasKey5 execution time: 2s 148.189608ms

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

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

如果你使用一个简单的对象作为哈希表并且从不做任何变态,我会使用if (obj[x])...,因为我发现它更具可读性。

玩得开心。

答案 11 :(得分:11)

您还可以使用the ES6 Reflect object

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

可以找到Reflect.has的MDN文档here

  

静态Reflect.has()方法的作用类似in operator

答案 12 :(得分:7)

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

if (x.hasOwnProperty('key'))

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

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

if (x.key !== undefined)

答案 13 :(得分:5)

hasOwnProperty“可用于确定对象是否具有指定属性作为该对象的直接属性; 与in运算符不同,此方法不会检查对象的原型链。”

所以最有可能的是,对于你的问题看来,你不想使用hasOwnProperty,它决定了属性是否作为直接附加到对象本身来存在。

如果您想确定您想要使用的原型链中是否存在该属性,例如:

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

我希望这会有所帮助。

答案 14 :(得分:4)

另一种相对简单的方法是使用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

虽然我们在一个拥有出色浏览器支持的世界中。因为这个问题太老了,我想我会加上这个: 从JS v1.8.5

开始使用是安全的

答案 15 :(得分:3)

不要这样做object.hasOwnProperty(key)),它真的很糟糕,因为这些方法可能被相关对象的属性所遮蔽 - 考虑{ hasOwnProperty: false } - 或者,对象可能是一个空对象{{1} }。

最好的方法是(Object.create(null))或:

Object.prototype.hasOwnProperty.call(object, key)

答案 16 :(得分:2)

为什么可以做的事情过于复杂:

var isProperty =  (objectname.keyname || "") ? true : false;

在大多数情况下简单明了...

答案 17 :(得分:2)

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)

有关更多信息,请检查here

答案 18 :(得分:2)

有方法&#34; hasOwnProperty&#34;存在于对象上,但不建议直接调用此方法,因为有时对象可能为null或对象上存在某些属性,如:{ hasOwnProperty: false }

更好的方法是:

&#13;
&#13;
// good
var obj = {"bar": "here bar desc"}
console.log(Object.prototype.hasOwnProperty.call(obj, "bar"));

// best
const has = Object.prototype.hasOwnProperty; // cache the lookup once, in module scope.
console.log(has.call(obj, "bar"));
&#13;
&#13;
&#13;

答案 19 :(得分:2)

带有反射的ECMA Script 6解决方案。创建包装器,如:

/**
Gets an argument from array or object.
The possible outcome:
- If the key exists the value is returned.
- If no key exists the default value is returned.
- If no default value is specified an empty string is returned.
@param obj    The object or array to be searched.
@param key    The name of the property or key.
@param defVal Optional default version of the command-line parameter [default ""]
@return The default value in case of an error else the found parameter.
*/
function getSafeReflectArg( obj, key, defVal) {
   "use strict";
   var retVal = (typeof defVal === 'undefined' ? "" : defVal);
   if ( Reflect.has( obj, key) ) {
       return Reflect.get( obj, key);
   }
   return retVal;
}  // getSafeReflectArg

答案 20 :(得分:2)

存在大规模贬值的风险,这是特定案例的另一种选择。 :)

如果要测试对象上的成员并想知道它是否已设置为以下内容:

  • &#39;&#39;
  • 未定义
  • 0 ...

然后你可以使用:

var foo = {};
foo.bar = "Yes, this is a proper value!";
if (!!foo.bar) {
        // member is set, do something
}

答案 21 :(得分:1)

您需要使用方法object.hasOwnProperty(property)。如果对象具有属性,则返回true;如果对象没有,则返回false。

答案 22 :(得分:1)

您可以使用以下方法-

var obj = {a:1}
console.log('a' in obj)               //1
console.log(obj.hasOwnProperty('a'))  //2
console.log(Boolean(obj.a))         //3

以下方法之间的区别如下-

  1. 在第一种和第三种方法中,我们不仅搜索对象,还搜索它的对象。 原型链也是如此。如果对象不具有该属性,但是 该属性将出现在其原型链中 真正。

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

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

  1. 第二种方法将仅检查其自身的属性。例如-

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

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

  1. 第一和第三之间的区别是,如果有一个属性的值未定义,则第三种方法将为false,而第一种方法将为true。

var obj = {
      b : undefined
    }
    console.log(Boolean(obj.b))
    console.log('b' in obj);

答案 23 :(得分:1)

展示如何使用this answer

const object= {key1: 'data', key2: 'data2'};

Object.keys(object).includes('key1') //returns true

我们也可以使用 indexOf,我更喜欢 includes

答案 24 :(得分:1)

hasOwnProperty() 方法返回一个布尔值,指示对象是否将指定的属性作为自己的属性(而不是继承它)。

const object1 = {};
object1.property1 = 42;

console.log(object1.hasOwnProperty('property1'));
// expected output: true

console.log(object1.hasOwnProperty('toString'));
// expected output: false

console.log(object1.hasOwnProperty('hasOwnProperty'));
// expected output: false

Know more

答案 25 :(得分:0)

您可以使用JSON.stringify功能来解决参考检查。

var obj = {};
// check object
JSON.stringify(obj) == JSON.stringify({}) // return true

答案 26 :(得分:0)

性能

今天2020.12.17我针对选定解决方案在Chrome v87,Safari v13.1.2和Firefox v83的MacOs HighSierra 10.13.6上进行测试。

结果

我仅比较解决方案A-F,因为它们为详细信息部分中的代码段中使用的所有案例提供了有效的结果。对于所有浏览器

  • 基于in(A)的解决方案是快速还是最快
  • 如果不存在密钥,则解决方案(E)对于大型对象的chrome最快,对于小型阵列的Firefox最快
  • 对于小型阵列,
  • 解决方案(F)最快(比其他解决方案快10倍以上)
  • 解决方案(D,E)很快
  • 基于losash has(B)的解决方案最慢

enter image description here

详细信息

我执行4个测试用例:

  • 当对象具有10个字段并且搜索到的键存在时-您可以HERE运行
  • 当对象具有10个字段且搜索关键字不存在时-您可以HERE运行它
  • 当对象具有10000个字段且搜索关键字存在时-您可以HERE运行
  • 当对象具有10000个字段且搜索关键字存在时-您可以HERE运行

以下代码段显示了解决方案之间的差异 A B C D E F G H I J K

// SO https://stackoverflow.com/q/135448/860099


// src: https://stackoverflow.com/a/14664748/860099
function A(x) {
  return 'key' in x
}

// src: https://stackoverflow.com/a/11315692/860099
function B(x) {
  return _.has(x, 'key')
}

// src: https://stackoverflow.com/a/40266120/860099
function C(x) {
  return Reflect.has( x, 'key')
}

// src: https://stackoverflow.com/q/135448/860099
function D(x) {
  return x.hasOwnProperty('key')
}

// src: https://stackoverflow.com/a/11315692/860099
function E(x) {
  return Object.prototype.hasOwnProperty.call(x, 'key')
}

// src: https://stackoverflow.com/a/136411/860099
function F(x) {
  function hasOwnProperty(obj, prop) {
      var proto = obj.__proto__ || obj.constructor.prototype;
      return (prop in obj) &&
          (!(prop in proto) || proto[prop] !== obj[prop]);
  }
  return hasOwnProperty(x,'key')
}

// src: https://stackoverflow.com/a/135568/860099
function G(x) {
  return typeof(x.key) !== 'undefined'
}

// src: https://stackoverflow.com/a/22740939/860099
function H(x) {
  return x.key !== undefined
}

// src: https://stackoverflow.com/a/38332171/860099
function I(x) {
  return !!x.key
}

// src: https://stackoverflow.com/a/41184688/860099
function J(x) {
  return !!x['key']
}

// src: https://stackoverflow.com/a/54196605/860099
function K(x) {
  return Boolean(x.key)
}


// --------------------
// TEST
// --------------------

let x1 = {'key': 1};
let x2 = {'key': "1"};
let x3 = {'key': true};
let x4 = {'key': []};
let x5 = {'key': {}};
let x6 = {'key': ()=>{}};
let x7 = {'key': ''};
let x8 = {'key': 0};
let x9 = {'key': false};
let x10= {'key': undefined};
let x11= {'nokey': 1};



let b= x=> x ? 1:0;

console.log('  1 2 3 4 5 6 7 8 9 10 11');

[A,B,C,D,E,F,G,H,I,J,K ].map(f=> {  
  console.log(
    `${f.name} ${b(f(x1))} ${b(f(x2))} ${b(f(x3))} ${b(f(x4))} ${b(f(x5))} ${b(f(x6))} ${b(f(x7))} ${b(f(x8))} ${b(f(x9))} ${b(f(x10))}  ${b(f(x11))} `
  )})
  
console.log('\nLegend: Columns (cases)');
console.log('1.  key = 1 ');
console.log('2.  key = "1" ');
console.log('3.  key = true ');
console.log('4.  key = [] ');
console.log('5.  key = {} ');
console.log('6.  key = ()=>{} ');
console.log('7.  key = "" ');
console.log('8.  key = 0 ');
console.log('9.  key = false ');
console.log('10. key = undefined ');
console.log('11. no-key ');
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js" integrity="sha512-90vH1Z83AJY9DmlWa8WkjkV79yfS2n2Oxhsi2dZbIv0nC4E6m5AbH8Nh156kkM7JePmqD6tcZsfad1ueoaovww==" crossorigin="anonymous"> </script>
  
This shippet only presents functions used in performance tests - it not perform tests itself!

这是铬的示例结果

enter image description here

答案 27 :(得分:0)

迭代对象自身属性的更好方法:

如果你想在不使用 hasOwnProperty() 检查的情况下迭代对象的属性, 使用 for(let key of Object.keys(stud)){} 方法:

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

完整示例以及与 for-in with hasOwnProperty() 的比较

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

答案 28 :(得分:0)

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

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

myObject.hasOwnProperty('myKey')

typeof myObject.myKey !== 'undefined'

最后一个被广泛使用,但是(正如其他答案和评论中指出的那样)它也可以匹配从对象原型派生的键。

答案 29 :(得分:0)

一些更简单和简短的选项,具体取决于特定用例:

  1. 要检查属性是否存在,无论值如何,请使用 in operator ("a" in b)
  2. 要检查变量的属性值,请使用 bracket notation (obj[v])
  3. 要检查属性值是否为真,请使用 optional chaining (?.)
  4. 要检查属性值布尔值,请使用 double-not / bang-bang / (!!)
  5. 要为空/未定义检查设置默认值,请使用 nullish coalescing operator (??)
  6. 要为 falsey 值检查设置默认值,请使用短路 logical OR operator (||)

运行代码片段以查看结果:

let obj1 = {prop:undefined};
console.log(1,"prop" in obj1);
console.log(1,obj1?.prop);

let obj2 = undefined;
//console.log(2,"prop" in obj2); would throw because obj2 undefined
console.log(2,"prop" in (obj2 ?? {}))
console.log(2,obj2?.prop);

let obj3 = {prop:false};
console.log(3,"prop" in obj3);
console.log(3,!!obj3?.prop);

let obj4 = {prop:null};
let look = "prop"
console.log(4,"prop" in obj4);
console.log(4,obj4?.[look]);

let obj5 = {prop:true};
console.log(5,"prop" in obj5);
console.log(5,obj5?.prop === true);

let obj6 = {otherProp:true};
look = "otherProp"
console.log(6,"prop" in obj6);
console.log(6,obj6.look); //should have used bracket notation

let obj7 = {prop:""};
console.log(7,"prop" in obj7);
console.log(7,obj7?.prop || "empty"); 

我很少看到正确使用 hasOwn 的情况,特别是考虑到它的 inheritance issues

答案 30 :(得分:-1)

如果您要检查的密钥存储在变量中,您可以这样检查:

x = {'key': 1};
y = 'key';
x[y];

答案 31 :(得分:-2)

我用了这个。如果对象中有对象,这对我有很大帮助

if(typeof(obj["key"])=="string"){
    alert("property");
}