我已经看到了两种检测UA是否实现特定JS属性的方法:if(object.property)
和if('property' in object)
。
我想听听哪些更好,更重要的是为什么的意见。一个明显优于另一个吗?是否有不仅仅是这两种方法来进行对象属性检测?请涵盖浏览器支持,陷阱,执行速度等,而不是美学。
修改:鼓励读者在jsperf.com/object-detection
运行测试答案 0 :(得分:115)
if(object.property)
将会失败,和会被设置为某些假值,例如和。 undefined
,null
,0
等(这不是您想要的)。
var object = {property: 0};
if(object.isNotSet) { ... } // will not run
if(object.property) { ... } // will not run
if('property' in object)
略好一些,因为它实际上会返回对象是否具有该属性,而不仅仅是查看其值。
var object = {property: 0};
if('property' in object) { ... } // will run
if('toString' in object) { ... } // will also run; from prototype
if(object.hasOwnProperty('property'))
甚至更好,因为它允许您区分实例属性和原型属性。
var object = {property: 0};
if(object.hasOwnProperty('property')) { ... } // will run
if(object.hasOwnProperty('toString')) { ... } // will not run
我会说性能在这里不是一个大问题,除非你每秒检查数千次,但在这种情况下你应该考虑另一种代码结构。最近的浏览器支持所有这些功能/语法,hasOwnProperty
也已存在很长时间了。
编辑:您还可以通过将任何内容(甚至是非对象的内容)作为对象传递来创建一个通用函数来检查属性是否存在:
function has(obj, prop) {
return Object.prototype.hasOwnProperty.call(obj, prop);
}
现在可行:
has(window, 'setTimeout'); // true
即使window.hasOwnProperty === undefined
(在IE 8或更低版本中就是这种情况)。
答案 1 :(得分:11)
这取决于你想要实现的目标。您是在谈论主机对象(例如window
和DOM节点)吗?如果是这样,最安全的检查是typeof
,它适用于我所知道的所有主机对象:
if (typeof object.property != "undefined") { ... }
注意:
object.hasOwnProperty()
主机对象,因为主机对象没有义务从Object.prototype
继承,因此可能没有hasOwnProperty()
方法(实际上在IE< 9中,它们通常是不要)。if (object.property) { ... }
)是对属性存在的不良测试,因为它会给虚假值假阴性。例如,对于空文本区域,即使属性存在,if (textarea.selectionStart) { ... }
也不会执行该块。此外,在尝试强制转换为布尔值(例如var xhr = new ActiveXObject("Microsoft.XMLHTTP"); if (xhr.responseXML) { ... }
)时,某些主机对象属性会在旧版本的IE中引发错误。 in
operator是对属性存在的更好测试,但再次无法保证在宿主对象中支持它。有关此问题的更多背景信息,我建议this excellent article by Peter Michaux。
答案 2 :(得分:2)
绝对if ('property' in object)
是正确的方法。这实际上测试了属性是否在对象中(或者在其原型链中,更多的是在下面)。
if (object.property)
会将“财产”强制转化为真实/ fla值。如果属性未设置,它将返回“undefined”,这将被强制为false,并且似乎有效。但是,对于许多其他属性值,这也将失败。 javascript在它被视为真实和虚假的东西方面是出了名的不一致。
最后,就像我上面所说的那样,'property' in 'object'
如果在原型链的任何地方都会返回true。如果你想测试对象本身,而不是链中的某个位置,你可以使用hasOwnProperty
方法,如下所示:
if (object.hasOwnProperty('property')) ...
答案 3 :(得分:0)
如果“property”为0,则第一个将失败。要确保实际存在属性,您需要检查object.property !== undefined
,或使用in-keyword。
还有hasOwnProperty函数,但我从来没有真正使用过那个,所以我不能说太多。虽然我认为如果属性设置在原型中(有时你想要的话),它会不会返回,有时你不想要它。
答案 4 :(得分:0)
这允许您使用window.hasOwnProperty作为引用自身或其他内容,无论您的脚本主机是什么。
// No enclosing functions here
if (!('hasOwnProperty' in this))
function hasOwnProperty(obj, prop) {
var method = Object.prototype.hasOwnProperty;
if (prop === undefined)
return method.call(this, obj);
return method.call(obj, prop);
}
//Example of use
var global = global || this; //environment-agnostic way to get the global object
var x = 'blah';
WScript.Echo(global.hasOwnProperty('x') ? 'true' : 'false'); //true
//Use as non-object method
var y = { z: false };
WScript.Echo(hasOwnProperty(y, 'z') ? 'true' : 'false'); //true
WScript.Echo(hasOwnProperty(y, 'w') ? 'true' : 'false'); //false
// true ಠ_ಠ
WScript.Echo(hasOwnProperty(global, 'hasOwnProperty') ? 'true' : 'false');