Published At:
Updated At:

JavaScriptのPrototypeオブジェクトについて

JavaScriptWebセキュリティ翻訳
Revision History
  • Migrate articles from Hatena Blog. (#1615cbe by 8ayac)

この記事は、dharani jayakanthan氏のIntro To Prototype - JSの翻訳記事です。

Prototype

JavaScriptで関数を作ると、JavaScriptエンジンが2つのオブジェクトを作ります。

JSエンジンが関数を処理するときに作られる2つのオブジェクトは、

  • その関数自体を呼び出すFunctionオブジェクト
  • Prototypeオブジェクト

prototypeとは

JSのprototypeとは、主に継承のために利用され、関数のprototypeプロパティにメソッドやプロパティを追加して、それらのメソッドとプロパティをその関数のインスタンスで利用できるようにします。

function foo() {
    console.log("Hello!!");
}
// foo.prototype

JSエンジンがprototypeオブジェクトを作ると、プロパティも同時に作られます。関数内のこのprototypeプロパティを使用して、その関数用に作られたprototypeオブジェクトにアクセスできます。

例えば、prototypeオブジェクトを指すprototypeという呼ばれるプロパティを持つfoo関数を見てきました。prototypeオブジェクトを使用するには、newというキーワードを使用してオブジェクトを作成します。

var myObj = new foo();
// myObj

myObjオブジェクトを作ると、JSエンジンはデフォルトで"__proto__"というオブジェクトを持つオブジェクトを作ります。これは、関数によって作られた最初のprototypeオブジェクトを指します。

__proto__を使ってみる

オブジェクトを生成すると、JSエンジンが__proto__オブジェクトを作ることがわかったので、それがどのように機能するかを見るために、myObjオブジェクト内にHi from myObj itselfという値を持つsayプロパティを作ってみましょう。

function foo() {}
var myObj = new foo();
myObj.say = "Hi from myObj itself";

myObj.sayにアクセスすると"Hi from myObj itself"という値が返されることがわかります。値の異なる同じ名前のプロパティを__proto__オブジェクトに作ります。

function foo() {}
var myObj = new foo();
myObj.__proto__.say = "Hi from proto object";

myObj.__proto__.sayにアクセスすると、"Hi from proto object"が返されます。

function foo(){}
var myObj = new foo();
myObj.say = "Hi from myObj itself";
// Hi from myObj itself
myObj.__proto__.say = "Hi from proto object";
// Hi from proto object
delete myObj.say;
// true
myObj.say
// Hi from proto object

しかし、myObj.sayを削除してから、それにアクセスしたとき、JSエンジンはsayというプロパティが存在するかを確認するために、__proto__オブジェクトを調べます。そして、"Hi from proto object"という値を持つプロパティmyObj.__proto__.sayが発見され、その値が返されます。

オブジェクトを作ると、JSエンジンは必ずprototypeと呼ばれる別のオブジェクトを作ります。そのprototypeには、.prototypeというキーワードを使用することでアクセスできます。しかし、newというキーワードを使ってオブジェクトを使ってオブジェクトを作った場合には、JSはprototypeオブジェクトを指す__proto__を作ります。

オブジェクト内のプロパティを探すと、JSエンジンがオブジェクト自体の中にそれを発見した場合、それが返されます。もし、そのようなプロパティが存在しない場合は、JSエンジンはprototypeオブジェクトを調べます。