How do I check if an object has a property in JavaScript?
如何检查一个对象在javascript中是否有属性?
考虑:
1 2 3 4 | x = {'key': 1}; if ( x.hasOwnProperty('key') ) { //Do this } |
这是最好的方法吗?
我真的被给出的答案弄糊涂了——大多数答案都是完全错误的。当然,您可以拥有具有未定义、空或假值的对象属性。因此,简单地将财产检查减少到
这取决于你在找什么。如果您想知道一个对象在物理上是否包含一个属性(并且它不是来自原型链上的某个位置),那么
如果您要查找的是一个对象上是否有一个不可重写的属性(当您迭代该对象的属性时,它会出现),那么执行:
由于使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | 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 ); } } |
上面是一个有效的跨浏览器的
使用
1 | _.has(x, 'key'); |
它调用
特别是,lodash将
1 2 3 4 | function has(object, key) { return object ? hasOwnProperty.call(object, key) : false; } // hasOwnProperty = Object.prototype.hasOwnProperty |
注:由于严格模式和
记住,如果您不使用严格模式,那么
因此,一种更为稳健的方法是:
1 | if (typeof(x.attribute) !== 'undefined') |
另一方面,这种方法更冗长,速度也更慢。- -
一种常见的替代方法是确保
1 2 3 4 5 | (function (undefined) { … your code … if (x.attribute !== undefined) … mode code … })(); |
怎么样?
1 2 3 4 5 | var x = {'key': 1}; if ('key' in x) { console.log('has'); } |
1 | if (x.key !== undefined) |
Armin Ronacher似乎已经打败了我,但是:
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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!'); } |
康拉德·鲁道夫(KonradRudolph)和阿敏·罗纳赫(Armin Ronacher)指出,一个更安全但速度较慢的解决方案是:
1 2 3 | Object.prototype.hasOwnProperty = function(property) { return typeof this[property] !== 'undefined'; }; |
可以使用
1 2 | x = {'key': 1}; alert("key" in x); |
您还可以使用
1 2 3 4 5 | for (prop in x) { if (prop =="key") { //Do something } } |
必须考虑此对象属性是否可枚举,因为不可枚举的属性不会显示在
如果需要所有实例属性的列表,无论是否可枚举,都可以使用
1 | Object.getOwnPropertyNames(x); |
这将返回对象上存在的所有属性的名称数组。
最后,可以使用type of运算符直接检查对象属性的数据类型:
1 2 3 | if (typeof x.key =="undefined") { alert("undefined"); } |
如果对象上不存在该属性,它将返回未定义的字符串。否则,它将返回适当的属性类型。但是,请注意,这并不总是检查对象是否具有属性的有效方法,因为您可以将属性设置为未定义,在这种情况下,使用
更新:通过与未定义的javascript属性比较,可以检查属性是否存在。
1 2 3 | if (x.key === undefined) { alert("undefined"); } |
除非X对象上的key被专门设置为
让我们在这里解决一些困惑。首先,假设
如果传递给它的属性名已添加到对象中,则
因此:
1 2 3 4 5 | var o = {} o.x = undefined var a = o.hasOwnProperty('x') // a is true var b = o.x === undefined // b is also true |
然而:
1 2 3 4 | var o = {} var a = o.hasOwnProperty('x') // a is now false var b = o.x === undefined // b is still true |
问题是,当原型链中的对象具有值为"未定义"的属性时会发生什么?
底线是没有跨浏览器的方法(因为Internet Explorer不公开
如果您正在搜索属性,则选择"否"。你想要:
1 | if ('prop' in obj) { } |
一般来说,您不应该关心属性是否来自原型或对象。
但是,因为您在示例代码中使用了"key",所以看起来您将对象视为散列,在这种情况下,您的答案是有意义的。所有散列键都是对象中的属性,您可以避免原型提供的额外属性。
约翰·雷西格的回答很全面,但我觉得不清楚。尤其是在obj中使用"prop"时。
是的,我认为你也可以做
但这是对自身属性的测试。如果你想检查它是否有一个属性,也可能是固有的,你可以使用
1 2 3 | if (typeof x.key !="undefined") { } |
因为
1 | if (x.key) |
如果
对于测试简单对象,请使用:
如果不知道它使用的对象类型:
所有其他选项都比较慢。
细节
在Nodejs下对其他人建议的5个选项进行100000000个周期的性能评估:
1 2 3 4 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)); } |
评估告诉我们,除非我们特别想检查对象的原型链以及对象本身,否则我们不应该使用通用形式:
1 2 3 4 5 | 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.hasownpropy(x))…"。
否则,当使用一个简单的对象而不担心对象的原型链时,使用
如果您使用一个简单的对象作为哈希表,并且从不做任何奇怪的事情,那么我会使用
玩得高兴。
您还可以使用es6
1 2 | x = {'key': 1}; Reflect.has( x, 'key'); // returns true |
有关
The static
Reflect.has() method works like the in operator as a function.
好吧,看起来我的回答是对的,除非你不想继承财产:
1 | if (x.hasOwnProperty('key')) |
以下是一些包含继承属性的其他选项:
1 2 3 | if (x.key) // Quick and dirty, but it does the same thing as below. if (x.key !== undefined) |
"hasownProperty"可用于确定对象是否具有指定的属性作为该对象的直接属性;与in运算符不同,此方法不检查对象的原型链。
因此,最可能的情况是,对于您的问题,您不想使用hasownpropy,它决定了属性是否直接附加到对象本身。
如果要确定原型链中是否存在该属性,您主要希望在其中使用,例如:
1 | if( prop in object ){ // do something } |
我希望这有帮助。
另一个相对简单的方法是使用
1 2 3 4 5 | 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开始使用是安全的
不要这样做
最好的方法是执行
1 2 3 4 5 | const has = Object.prototype.hasOwnProperty; // cache the lookup once, in module scope. /* or */ import has from 'has'; // https://www.npmjs.com/package/has // ... console.log(has.call(object, key)); |
考虑到大量投票被否决的风险,这里是另一个具体案例的选择。:)
如果要测试对象上的成员,并想知道是否已将其设置为以下内容以外的其他内容:
- ’
- 假
- 无效的
- 未定义
- 零…
然后您可以使用:
1 2 3 4 5 | var foo = {}; foo.bar ="Yes, this is a proper value!"; if (!!foo.bar) { // member is set, do something } |
带反射的ECMA脚本6解决方案。创建包装方式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | /** 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 |
对象上存在方法"hasOwnProperty",但不建议直接调用此方法,因为有时对象可能为空或对象上存在某些属性,如:
所以更好的方法是:
1 2 3 4 5 6 7 | // 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")); |
当你能做到的时候,为什么过于复杂化?
1 | var isProperty = (objectname.keyname ||"") ? true : false; |
简单明了,适用于大多数情况…
您可以使用以下方法-
1 2 3 4 | var obj = {a:1} console.log('a' in obj) //1 console.log(obj.hasOwnProperty('a')) //2 console.log(Boolean(obj.a)) //3 |
以下方法的区别如下-
1 2 3 4 5 6 7 | var obj = { a:2, __proto__ :{b:2} } console.log('b' in obj) console.log(Boolean(obj.b)) |
1 2 3 4 5 6 | var obj = { a:2, __proto__ :{b:2} } console.log(obj.hasOwnProperty('b')) |
1 2 3 4 5 | var obj = { b : undefined } console.log(Boolean(obj.b)) console.log('b' in obj); |
您需要使用方法
如果要检查的键存储在变量中,可以这样检查:
1 2 3 | x = {'key': 1}; y = 'key'; x[y]; |
我用过这个。如果你有一个物体在物体里面,这对我有很大帮助
1 2 3 | if(typeof(obj["key"])=="string"){ alert("property"); } |