私が正しく理解していれば、JavaScriptのすべてのオブジェクトはObjectプロトタイプから継承します
髪の毛を分割するように見えるかもしれませんが、JavaScript(ECMAScript実装の総称)とECMAScript(JavaScript実装に使用される言語)には違いがあります。JavaScriptではなく継承スキームを定義するのはECMAScriptなので、ネイティブECMAScriptオブジェクトのみがその継承スキームを実装する必要があります。
実行中のJavaScriptプログラムは、少なくとも組み込みのECMAScriptオブジェクト(オブジェクト、関数、数値など)と、おそらくいくつかのネイティブオブジェクト(関数など)で構成されています。また、一部のホストオブジェクト(ブラウザーのDOMオブジェクト、または他のホスト環境のその他のオブジェクト)が含まれる場合もあります。
組み込みオブジェクトとネイティブオブジェクトはECMA-262で定義された継承スキームを実装する必要がありますが、ホストオブジェクトは実装しません。したがって、JavaScript環境のすべてのオブジェクトがObject.prototypeから継承する必要はありません。たとえば、ActiveXオブジェクトとして実装されたIEのホストオブジェクトは、ネイティブオブジェクトとして扱われるとエラーをスローします(そのため、MS XMLHttpRequestオブジェクトを初期化するためにtry..catchが使用される理由)。一部のDOMオブジェクト(互換モードのIEのNodeListsなど)は、Arrayメソッドに渡されるとエラーをスローし、IE 8以下のDOMオブジェクトにはECMAScriptのような継承スキームがありません。
したがって、JavaScript環境のすべてのオブジェクトがObject.prototypeを継承するとは限りません。
つまり、JavaScriptのすべてのオブジェクトは、プロトタイプチェーンを通じてhasOwnProperty関数にアクセスできます。
これは少なくとも、互換モード(および常にIE 8以下)のIEの特定のホストオブジェクトには当てはまりません。
上記を踏まえて、オブジェクトが独自のhasOwnPropertyメソッドを持っている理由と、それが良いアイデアかどうかを最初にテストせずに、代わりに他のhasOwnPropertyメソッドを呼び出すことの妥当性について考えてみる価値があります。
編集する
使用する理由Object.prototype.hasOwnProperty.call
は、一部のブラウザではホストオブジェクトにhasOwnPropertyメソッドがなく、callを使用しており、組み込みのメソッドが代替であるためだと思います。ただし、一般的にそうすることは、上記の理由により、良い考えのようには思えません。
ホストオブジェクトが関係する場合、in演算子を使用して、一般的にプロパティをテストできます。
var o = document.getElementsByTagName('foo');
// false in most browsers, throws an error in IE 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');
代替(IE6などでテスト済み):
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オブジェクトサポートをテストする一般的な(そして一見成功している)方法です。