この記事は、dharani jayakanthan氏のIntro To Prototype - JSの翻訳記事です。
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
オブジェクトを調べます。