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));
// 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"));
10
hasOwnProperty“可用于确定对象是否具有指定的属性作为该对象的直接属性; unlike the in operator ,此方法不会检查对象的原型链 . ”
所以很可能,对于你的问题看来,你不想使用hasOwnProperty,它决定了属性是否作为附加 directly to the object itself 存在 .
如果你想确定你想要使用的原型链中是否存在该属性,例如:
if( prop in object ){ // do something }
我希望这有帮助 .
8
由于存在大规模贬值的风险,这是特定案例的另一种选择 . :)
如果要测试对象上的成员并想知道它是否已设置为以下内容:
''
假
null
undefined
0 ......
然后你可以使用:
var foo = {};
foo.bar = "Yes, this is a proper value!";
if (!!foo.bar) {
// member is set, do something
}
110
为什么你可以做的事情过于复杂:
var isProperty = (objectname.keyname || "") ? true : false;
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 );
}
}
/**
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
23 回答
假设
hasOwnProperty
已存在,让's cut through some confusion here. First, let'简化;对于当前使用的绝大多数浏览器来说都是如此 .如果传递给它的属性名称已添加到对象,
hasOwnProperty
将返回true . 它完全独立于分配给它的实际值,可能正好是undefined
.Hence:
However:
问题是当原型链中的对象具有值为undefined的属性时会发生什么?
hasOwnProperty
将为false,!== undefined
也是如此 . 然而,for..in
仍然会在枚举中列出它 .底线是没有跨浏览器方式(因为Internet Explorer不公开
__prototype__
)以确定特定标识符尚未附加到对象或其原型链中的任何内容 .您需要使用方法
object.hasOwnProperty(property)
. 如果对象具有属性,则返回true;如果对象不具有该属性,则返回false .不要这样做
object.hasOwnProperty(key))
,它真的很糟糕,因为这些方法可能被相关对象的属性所遮蔽 - 考虑{ hasOwnProperty: false }
- 或者,该对象可能是一个空对象(Object.create(null))
.最好的方法是
Object.prototype.hasOwnProperty.call(object, key)
或:你也可以使用the ES6 Reflect object:
有关
Reflect.has
的MDN文档可以在here找到 .对象上存在方法"hasOwnProperty",但不建议直接调用此方法,因为有时对象可能为null或对象上存在某些属性,如:
{ hasOwnProperty: false }
所以更好的方法是:
hasOwnProperty“可用于确定对象是否具有指定的属性作为该对象的直接属性; unlike the in operator ,此方法不会检查对象的原型链 . ”
所以很可能,对于你的问题看来,你不想使用hasOwnProperty,它决定了属性是否作为附加 directly to the object itself 存在 .
如果你想确定你想要使用的原型链中是否存在该属性,例如:
我希望这有帮助 .
由于存在大规模贬值的风险,这是特定案例的另一种选择 . :)
如果要测试对象上的成员并想知道它是否已设置为以下内容:
''
假
null
undefined
0 ......
然后你可以使用:
为什么你可以做的事情过于复杂:
大多数情况下简单明了......
我对所给出的答案感到困惑 - 大多数答案都是完全不正确的 . 当然,您可以拥有具有undefined,null或false值的对象属性 . 因此,简单地将属性检查减少到
typeof this[property]
,或者更糟糕的是,x.key
会给你带来完全误导性的结果 .这取决于你在寻找什么 . 如果你想知道一个对象是否物理上包含一个属性(并且它不是来自原型链上的某个地方),那么
object.hasOwnProperty
就是你要走的路 . 所有现代浏览器都支持它 . (在旧版本的Safari - 2.0.1及更早版本中缺少它 - 但是浏览器的那些版本很少被使用 . )如果你正在寻找的是一个对象上有一个可迭代的属性(当你迭代对象的属性时,它会出现)然后做:
prop in object
将给你你想要的效果 .因为使用
hasOwnProperty
可能是您想要的,并且考虑到您可能需要回退方法,我向您呈现以下解决方案:以上是一个有效的,跨浏览器的
hasOwnProperty
解决方案,但有一点需要注意:它无法区分原型和实例上相同属性的情况 - 它只是假设它来自原型 . 根据你的情况,你可以把它转移到更宽松或更严格的程度,但至少这应该更有帮助 .因为
如果
x.key
解析为false
(例如,x.key = ""
),则会失败 .另一种相对简单的方法是使用Object.keys . 这将返回
array
,这意味着您将获得数组的所有功能 .虽然我们在一个拥有出色浏览器支持的世界中 . 因为这个问题已经太老了,我想我会添加这个:从JS v1.8.5起这是安全的
如果您要检查的密钥存储在变量中,您可以这样检查:
我用过这个 . 如果你在对象里面有一个对象,这对我很有帮助
Note :由于严格模式,以下现在基本上已经过时了,
hasOwnProperty
. 正确的解决方案是使用严格模式并使用obj.hasOwnProperty
检查属性是否存在 . 这个答案早于这两个方面,至少同样广泛实施(是的,它是旧的) . 请将以下内容作为历史记录 .请记住,如果您没有使用严格模式,
undefined
(遗憾的是)不是JavaScript中的保留字 . 因此,某人(显然是其他人)可能会有重新定义它的宏伟想法,破坏您的代码 .因此,更强大的方法如下:
另一方面,这种方法更冗长,也更慢 . : - /
一种常见的替代方法是确保
undefined
实际上是未定义的,例如将代码放入一个函数中,该函数接受一个名为undefined
的附加参数,该函数不传递值 . 为了确保它没有传递一个值,你可以立即自己调用它,例如:Armin Ronacher似乎已经beat me to it,但是:
一个更安全但更慢的解决方案as pointed out by Konrad Rudolph和Armin Ronacher将是:
好的,看起来我有正确的答案,除非你不想要继承的属性:
以下是包含继承属性的其他一些选项:
如果您正在寻找房产,那么“不” . 你要:
通常,您不应该关心属性是来自原型还是对象 .
但是,因为您在示例代码中使用了“key”,所以看起来您将对象视为哈希,在这种情况下,您的答案是有意义的 . 所有哈希键都是对象中的属性,并且您可以避免原型提供的额外属性 .
John Resig的回答非常全面,但我认为还不清楚 . 特别是何时在obj中使用“'prop'” .
您可以使用
in
运算符来检查对象上是否存在该属性:您还可以使用
for - in
循环遍历对象的所有属性,然后检查特定属性:您必须考虑此对象属性是否可枚举,因为非可枚举属性不会显示在
for-in
循环中 . 此外,如果可枚举属性正在遮蔽原型的非可枚举属性,则它将不会显示在Internet Explorer 8及更早版本中 .如果您想要所有实例属性的列表,无论是否可枚举,您都可以使用
这将返回对象上存在的所有属性的名称数组 .
最后,您可以使用typeof运算符直接检查对象属性的数据类型:
如果对象上不存在该属性,则返回字符串undefined . 否则它将返回适当的属性类型 . 但是,请注意,这并不总是检查对象是否具有属性的有效方法,因为您可以将属性设置为undefined,在这种情况下,使用
typeof x.key
仍将返回true(即使键是仍在对象中) .更新:您可以通过与未定义的javascript属性进行比较来检查属性是否存在
除非在x对象上专门设置为
undefined
,否则这应该有效使用Underscore.js或(even better)lodash:
哪个调用
Object.prototype.hasOwnProperty
,但是(a)键入的时间较短,而(b)使用“hasOwnProperty
的安全引用”(即,即使hasOwnProperty
被覆盖也有效) .特别是,lodash将
_.has
定义为:关于什么?
要测试简单对象,请使用: if (obj[x] !== undefined)
如果您不知道它使用的是哪种对象类型: if (obj.hasOwnProperty(x))
所有其他选项都比较慢..
Details
在Nodejs下的100,000,000个周期的性能评估到其他人建议的5个选项:
评估告诉我们,除非我们特别想检查对象的原型链以及对象本身,否则我们不应该使用通用形式:
if (X in Obj)...
It is between 2 to 6 times slower depending on the use case最重要的是,如果您的Obj不一定是一个简单的对象,并且您希望避免检查对象的原型链并确保x直接由Obj拥有,请使用'if(obj.hasOwnProperty(x))...' .
否则,当使用简单对象而不担心对象的原型链时,使用
if (typeof(obj[x]) !== 'undefined')...
是最安全和最快捷的方式 .如果你使用一个简单的对象作为哈希表并且从不做任何变态,我会使用
if (obj[x])...
,因为我发现它更具可读性 .玩得开心 .
是的它是:)我认为你也可以做
Object.prototype.hasOwnProperty.call(x, 'key')
如果x
有一个名为hasOwnProperty
的属性也应该工作但是那可以测试自己的属性 . 如果要检查它是否具有可能已被连接的属性,则可以使用
typeof x.foo != 'undefined'
.ECMA Script 6解决方案与反映 . 创建包装如下: