如何检查一个对象是否在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.key
parsing为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"));