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

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

考虑:

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

这是做这件事的最好方法吗?

我真的很困惑已经给出的答案 – 其中大多数是完全不正确的。 当然,你可以拥有未定义,空值或假值的对象属性。 所以简单地减less属性检查来typeof this[property]或者更糟的是, x.key会给你完全误导的结果。

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

如果你正在寻找的是一个对象有一个可迭代的属性(当你遍历对象的属性,它会出现),然后做: prop in object将给你你想要的效果。

由于使用hasOwnProperty可能是你想要的,考虑到你可能需要一个回退方法,我向你展示了以下解决scheme:

 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一个工作的,跨浏览器的解决scheme,但有一点需要注意:无法区分原型和实例上具有相同属性的情况 – 它只是假定它来自原型。 根据你的情况,你可以把它变得更宽松或者更严格,但是至less这应该是更有帮助的。

随着lodash或( 甚至更好 ) lodash

 _.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 

注意 :以下是由于严格模式而已经基本过时了,并且具有hasOwnProperty 。 正确的解决scheme是使用严格模式,并使用obj.hasOwnProperty检查是否存在属性。 这个答案早于这两件事情,至less是广泛实施的(是的,那是旧的)。 以下列为历史logging。


请记住,如果您不使用严格模式,那么undefined (不幸的是) 不是 JavaScript中的保留字。 因此,某个人(显然是别人)可能有重新定义它的想法,破坏你的代码。

因此更健壮的方法是:

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

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

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

 (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 Rudolph和Armin Ronacher 指出的那样 ,一个更安全但缓慢的解决scheme是:

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

您可以使用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运算符来直接检查对象属性的数据types:

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

如果该对象上不存在该属性,它将返回未定义的string。 否则它将返回适当的属性types。 但是,请注意,这并不总是检查对象是否有属性的有效方法,因为您可以将属性设置为undefined,在这种情况下,使用typeof x.key仍然会返回true(即使关键还在于对象)。

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

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

这应该工作,除非在x对象上专门设置了undefined

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

hasOwnProperty返回true,如果传递给它的属性名已经添加到对象中。 它完全独立于分配给它的实际值,可能完全undefined

因此:

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

然而:

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

问题是当原型链中的一个对象具有undefined值的属性时会发生什么? hasOwnProperty将为false,所以将会是!== undefined 。 然而,..in仍然会列举在枚举中。

底线是没有跨浏览器的方式(因为Internet Explorer不公开__prototype__)来确定一个特定的标识符没有被附加到一个对象或其原​​型链中的任何东西。

如果你正在寻找一个属性,那么“否”。 你要:

 if ('prop' in obj) { } 

一般来说,你不应该在乎财产是否来自原型或对象。

但是,因为在示例代码中使用了“键”,所以看起来您将该对象视为散列,在这种情况下,您的答案才有意义。 所有的哈希键都是对象中的属性,并且避免了原型贡献的额外属性。

约翰·雷西格的回答非常全面,但我认为还不清楚。 特别是在什么时候使用obj中的“'prop'”。

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

但是,testing自己的属性。 如果你想检查它是否有一个属性,也可能会embedded,你可以使用typeof x.foo != 'undefined'

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

因为

 if (x.key) 

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

您也可以使用ES6 Reflect对象 :

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

有关MDN for Reflect.has文档可以在这里find。

静态Reflect.has()方法与in运算符一样起作用。

对于testing简单对象使用: if (obj[x] !== undefined)

如果你不知道它使用什么对象types: if (obj.hasOwnProperty(x))

所有其他选项都比较慢

细节

在Nodejs下的100,000,000个周期对其他人build议的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)); } 

评估告诉我们,除非我们特别要检查对象的原型链以及对象本身,否则我们不应该使用常见的forms: 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])...因为我发现它更可读。

玩的开心。

好吧,看起来我有正确的答案,除非你不想要inheritance的属性:

 if (x.hasOwnProperty('key')) 

这里有一些其他的选项来包含inheritance的属性:

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

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

所以最有可能的是,对于你的问题似乎你不想使用hasOwnProperty,它确定属性是否存在直接附加到对象本身

如果你想确定这个属性是否存在于你想要使用的原型链中,比如:

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

我希望这有帮助。

另一个比较简单的方法是使用Object.keys 。 这将返回一个array ,这意味着您可以获得array所有function。

 var noInfo = {}; var info = {something: 'data'}; Object.keys(noInfo).length //returns 0 or false Object.keys(info).length //returns 1 or true 

尽pipe我们处于一个浏览器支持良好的世界。 由于这个问题是如此之大,我想我会补充一点:从JS v1.8.5开始,这是安全的

面临大规模下调风险,这是另一个具体案例的select。 🙂

如果你想testing一个对象上的成员,并想知道它是否被设置为以下内容:

  • “”
  • 空值
  • 未定义
  • 0 …

那么你可以使用:

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

用ECMA Script 6解决scheme进行反思。 创build包装,如:

 /** 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 

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

如果你正在检查的密钥存储在一个variables中 ,你可以这样检查:

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

你也可以使用这个我写的名为object-hasOwnProperty的开源可重用组件。

例:

 hasOwnProperty({foo: 'bar'}, 'foo') // => true hasOwnProperty({foo: 'bar'}, 'bar') // => false 

这很简单:

 function hasOwnProperty(obj: {}, prop: string|number): boolean { return Object.prototype.hasOwnProperty.call(obj, prop); }; 

在对象上存在方法“hasOwnProperty”,但不build议直接调用此方法,因为有时对象可能为null或某个属性存在于对象上: { hasOwnProperty: false }

所以更好的方法是:

 // 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"));