LoginSignup
21
22

More than 5 years have passed since last update.

すべてのオブジェクトがObjectを継承している訳じゃない

Last updated at Posted at 2014-03-06

MDNいわく

JavaScript におけるすべてのオブジェクトは Object に由来します。 すべてのオブジェクトは Object.prototype からメソッドとプロパティを継承しています が、それらは上書きされている可能性があります。

らしい、だけどオブジェクトの中にはObjectを継承していないものがある。

追記
優しい人に教えてもらったのだけど、IE8およびIE7はじゃなくてJavaScriptじゃなくてJScriptというJavaScript互換言語でスクリプトを実行している。なのでMDNに書かれていることは正しい。紛らわしいこと書いてごめんなさい。
追記終わり。

JScriptのオブジェクトの中にはObjectを継承していないものがある。
具体例を出すとIE7でのwindowオブジェクトやDOM Events。
さらにIE7でのwindow.toStringFunctionを継承していない。

alert(window instanceof Object); // IE7ではfalse
alert(window.toString instanceof Function); // IE7ではfalse

以下、どうしてこんなことになっているか調べた。

native object, built-in object, host object

JScriptの標準言語仕様であるECMAScriptによると、オブジェクトは3つに分類できる。

  • native object

ホスト環境(つまりブラウザとかNode)から独立したオブジェクト。後述のbuilt-in objectと自分で作った(ユーザ定義した)オブジェクトがこれにあたる。

  • built-in object

ECMASciriptで定義されているオブジェクト。すべてのbuilt-in objectはnative objectでもある。ObjectFunctionDateなどおなじみのオブジェクトがこれ。

  • host object

ホスト環境から提供されるオブジェクト。ブラウザでいうwindowやDOM、Nodeでいうrequireなどがこれにあたる。

Objectの継承について

ECMAScript5.1によると

Unless otherwise specified every built-in prototype object has the Object prototype object, which is the initial value of the expression Object.prototype (15.2.4), as the value of its [[Prototype]] internal property, except the Object prototype object itself.

(てきとうな意訳)特に断りのない場合、すべてのbuilt-in prototype objectの[[Prototype]]内部プロパティはObject.prototypeを初期値として持っている、とある。

つまり基本的に built-in objectObjectをプロトタイプ継承しているよ、ということだ。
でも、逆にbuilt-in object以外についてはObjectを継承する、ということが明記されていない。

つまり?

built-in object以外はObjectを継承していなくても、ECMAScriptの仕様上間違いではないので host object であるwindowなどはObjectを継承していなくてもよい。

すべてのオブジェクトがObjectを継承しているだろうと思って、うっかりIE7で

// IE7
document.getElementById('btn').attachEvent('onclick', function (e) {
  if (e.hasOwnProperty('target')) {
    // 処理
  }
});

とかやってしまうと、エラーになる(host objectであるEventObjectを継承しておらずObject.prototype.hasOwnpropertyを参照しないため)。

関数についても同様のことがいえるので、IE7だと下記がエラーになる。

var obj = {};
window.toString.call(obj); // Functionを継承していないのでFunction.prototype.callを使えない

まとめ

host objectがObjectを継承してるかどうかは実行環境の実装によるので、気をつけよう。。

21
22
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
21
22