読者です 読者をやめる 読者になる 読者になる

ほげほげ(仮)

仮死状態

オブジェクトのプロパティとプロトタイプについて

JavaScript


プロパティとプロトタイプについて簡単にまとめておきます。

プロパティについて


次のようにプロパティを持ったオブジェクトを生成することができます。

// コンストラクタ
function Test(a, b) {
    // プロパティ初期化
    this.v1 = a;
    this.v2 = b;
}

var t1 = new Test(1, 2);
var t2 = new Test(3, 4);
alert(t1.v1);    // 1
alert(t1.v2);    // 2
alert(t2.v1);    // 3
alert(t2.v2);    // 4


プロパティはインスタンスごとに値が保持されます。


また次のように、インスタンス生成後にあとから追加することも可能です。

var t1 = new Test(1, 2);

t1.v3 = 'abc';   // プロパティ追加

alert(t1.v3);    // abc

プロトタイプについて


JavaScriptではすべてのオブジェクトはプロトタイプオブジェクトへの参照を含みます。

プロトタイプオブジェクトのプロパティはこのオブジェクトのプロパティとして参照可能です。

なんだかよく分からないですが、次のソースを見ればだいたい分かると思います。

function Test(a, b) {
    this.v1 = a;
    this.v2 = b;
}
// プロトタイプにプロパティに追加
Test.prototype.sum = function () {
    return this.v1 + this.v2;
}

var t1 = new Test(1, 2);

alert(t1.sum());    // 3

上の例ではプロパティとしてメソッドを定義しています。


これを別の方法で書いてみたいと思います。

function Test(a, b) {
    this.v1 = a;
    this.v2 = b;
    // プロパティとしてメソッドを定義
    this.sum = function () {
        return this.v1 + this.v2;
    }
}
var t1 = new Test(1, 2);

alert(t1.sum());    // 3


この方法でも先ほどのソースと同じ結果になります。


しかし、このようなメソッドを定義する場合は、プロトタイプを使ったほうが効率が良いです。

理由としては、プロトタイプオブジェクトは同じオブジェクトで共有されるからです。


次のように多くのインスタンスを生成した場合

function Test(a, b) {
    this.v1 = a;
    this.v2 = b;
}
Test.prototype.sum = function () {
    return this.v1 + this.v2;
}
var t1 = new Test(1, 2);
var t2 = new Test(3, 4);
var t3 = new Test(5, 6);
var t4 = new Test(7, 8);
var t5 = new Test(9, 10);

プロトタイプを使わない方法ですと、すべての変数が sum というメソッドを持つことになりますが、

プロトタイプを使うと共有されるため、メモリの消費量が減ります。

メモリ消費や効率を考えて、オブジェクト共通のメソッドやあとは定数もプロトタイプで定義したほうが良いでしょう。

プロパティへのアクセス


次のようなソースがある場合、結果はどうなるでしょう?

function Test() {
}
// プロトタイプに追加
Test.prototype.foo = "abc";

var t1 = new Test();

alert(t1.foo);

// プロパティを追加
t1.foo = "def";

alert(t1.foo);

結果としては最初の alert で「abc」と表示され、次に「def」と表示されます。


JavaScriptではオブジェクトを読み出すときに、まずはオブジェクトのプロパティを探し、無ければプロトタイプのプロパティを探します。


先程のソースに少し手を加えて

function Test() {
}
Test.prototype.foo = "abc";

var t1 = new Test();
alert(t1.foo);    // abc
t1.foo = "def";
alert(t1.foo);    // def

// プロパティを削除
delete t1.foo;

alert(t1.foo);    //abc

下の2行を追加しました。

delete によって foo プロパティが削除されるので、最後の alert ではプロトタイプのプロパティを参照するようになり、abc と再び表示されます。

まとめ


かなり簡単な説明になっちゃいました・・・

プロトタイプは少しややこしいのですが、慣れれば便利なものだと思います。

また、プロトタイプはJavaScriptオブジェクト指向を実現させるのに重要になるので、覚えておいたほうが良いと思います。

自分もまだまだ勉強中ですが(´゚ω゚`)


次はクラスの継承あたりを解説できればなぁって・・・気分しだいで( ´゚д゚`)