如果我理解正确的话,JavaScript 中的每个对象都继承自 Object 原型
这可能看起来像分裂头发,但JavaScript(ECMAScript 实现的通用术语)和ECMAScript(用于 JavaScript 实现的语言)之间是有区别的。定义继承方案的是 ECMAScript,而不是 JavaScript,因此只有原生 ECMAScript 对象需要实现该继承方案。
一个正在运行的 JavaScript 程序至少由内置的 ECMAScript 对象(对象、函数、数字等)和可能的一些本地对象(例如函数)组成。它也可能有一些宿主对象(例如浏览器中的 DOM 对象,或其他宿主环境中的其他对象)。
虽然内置对象和本机对象必须实现 ECMA-262 中定义的继承方案,但宿主对象不需要。因此,并非 JavaScript 环境中的所有对象都必须继承自Object.prototype。例如,在 Internet Explorer 中实现为ActiveX对象的主机对象如果被视为本机对象将引发错误(因此为什么使用 try..catch来初始化 Microsoft XMLHttpRequest对象)。某些 DOM 对象(如 Internet Explorer 中的怪癖模式中的 NodeLists)如果传递给 Array 方法将引发错误,Internet Explorer 8 及更低版本中的 DOM 对象没有类似 ECMAScript 的继承方案,等等。
因此,不应假定 JavaScript 环境中的所有对象都继承自 Object.prototype。
这意味着 JavaScript 中的每个对象都可以通过其原型链访问 hasOwnProperty 函数
至少对于处于怪异模式(以及 Internet Explorer 8 及更低版本)的 Internet Explorer 中的某些主机对象而言,这不是真的。
鉴于上述情况,值得思考为什么一个对象可能有自己的hasOwnProperty方法,以及调用其他一些hasOwnProperty方法而不首先测试是否是个好主意的可取性。
我怀疑使用的原因Object.prototype.hasOwnProperty.call
是在某些浏览器中,宿主对象没有hasOwnProperty方法,使用call和内置方法是一种替代方法。但是,由于上述原因,通常这样做似乎不是一个好主意。
在涉及宿主对象的情况下,in运算符通常可用于测试属性,例如
var o = document.getElementsByTagName('foo');
// false in most browsers, throws an error in Internet Explorer 6, and probably 7 and 8
o.hasOwnProperty('bar');
// false in all browsers
('bar' in o);
// false (in all browsers? Do some throw errors?)
Object.prototype.hasOwnProperty.call(o, 'bar');
另一种选择(在Internet Explorer 6和其他版本中测试):
function ownProp(o, prop) {
if ('hasOwnProperty' in o) {
return o.hasOwnProperty(prop);
} else {
return Object.prototype.hasOwnProperty.call(o, prop);
}
}
这样,您只需在对象没有它(继承或其他方式)的地方专门调用内置hasOwnProperty 。
然而,如果一个对象没有hasOwnProperty
方法,它可能同样适合使用in运算符,因为该对象可能没有继承方案并且所有属性都在该对象上(尽管这只是一个假设),例如in运算符是测试 DOM 对象对属性的支持的一种常见(并且看似成功)的方法。