【Javascript】プロトタイプって...何?

どーも!

たかぽんです!

今回はJavascriptのプロトタイプについて調べてみようと思います!

プロトタイプって...何?

さて、ではプロトタイプってなんでしょうか・・・?

Javascriptはプロトタイプベースのプログラミング言語で、このプロトタイプがコアになっているそうです。

MDNの解説は以下に記載があります。

上記ページの一番最初の行にありますが...

プロトタイプは JavaScript オブジェクトが機能を互いに継承するメカニズム

です。

んー?いまいちなんともわかんないですね。

文面だけ見るとJavaScriptでのオブジェクトが複数あって、お互いに機能を継承できるようにする何かなんでしょうね!

簡単な例をみていきましょう。

以下はコンストラクタ関数を定義しています。

その関数を使用してオブジェクトインスタンスを作成した場合、そのプロパティとしてproperty1, property2、そしてmethodという名前で関数が定義されています。

関数自体は自身のプロパティであるproperty1を返しているだけですね。

var Object1 = function(arg1, arg2) {
    this.property1 = arg1;
    this.property2 = arg2;
    this.method = function() {
        return this.property1;
    }
}

console.log(new Object1(1,2));

// 出力
{ property1: 1, property2: 2, method: [Function] }

この場合、”new Object(1,2)"を実行すると、その際propertyはもちろんですが、メソッドも合わせて新しいインスタンスとして作られます。

実際にconsole.logで確認をすると、Object1はプロパティとしてproperty1 = 1, propety2 = 2, そしてmethodという関数を持っていることがわかりますね。

そのため、以下のように書いたら、4回上記のようなオブジェクトを作ることになります。


console.log(new Object(1,2));
console.log(new Object(2,2));
console.log(new Object(3,2));
console.log(new Object(4,2));

つまり...メソッドもオブジェクトインスタンスが作られるたびに定義して作っていることになります。

実はいくつのインスタンスを作ったとしてもこのメソッドは一度の定義で済むんです...

その際に使うのがプロトタイプなんです...!

では試しに....

// 先ほど定義していたmethodは定義しない。
var Object1 = function(arg1, arg2) {
    this.property1 = arg1;
    this.property2 = arg2;
}

// prototypeとしてメソッドを定義する
Object1.prototype.prop1 = function() {
        return this.property1;
}

o1 = new Object1(1,2);
o2 = new Object1(2,2);

console.log(o1);
console.log(o2);
console.log(o1.prop1());
console.log(o2.prop1());

// o1インスタンスのプロトタイプの確認
console.log(Object.getPrototypeOf(o1));
console.log(o1.__proto__);

// 出力
Object1 { property1: 1, property2: 2 }
Object1 { property1: 2, property2: 2 }
1
2
Object1 { prop1: [Function] }
Object1 { prop1: [Function] }

さて、上記をみていただくと、プロトタイプとして定義したメソッドは作成したインスタンスに含まれていませんね!

最初に出力した二つのオブジェクトはプロパティしか持っていません。

しかしながら、その直後、インスタンスからprop1メソッドへアクセスすると、ちゃんと実行されています。

つまり、プロトタイプとしてメソッドを定義してあげると、インスタンス生成時には作成されていないけど、その参照情報を持っているため、結果的にメソッドを呼び出せるんです。

こうすることで不要なメソッドのコピーがなくなり、メモリを節約できるんですね!

また、インスタンスをみただけでは確認できませんでしたが、"Object.getPrototypeOf"というメソッドを使うことでそのオブジェクトのプロトタイプを確認することができます。

また、そのオブジェクトの"__proto__"へアクセスすることでもプロトタイプの確認が可能です。

最後に二つ出力していますね。

まとめ

今回はJavaScriptのプロトタイプについて調べてみました!

いろんなオブジェクトインスタンスで使いそうなメソッドはプロトタイプとして定義してあげれば比較的メモリを小さく使うことができそうですね!

こういうプログラミング言語のディープなところもしっかりと理解していけたらいいエンジニアになれるんでしょうね...きっと...

僕がいいエンジニアになれるのはまだまだ遠い道のりになりそうです...w

それでわ!

おすすめの記事