Home > 未分類 > javascriptのprototypeプロパティでハマった

javascriptのprototypeプロパティでハマった

トラックバックURL:

どうも。shimazakiです。

javascriptでprototypeプロパティについてアレコレしていたら自分が大きく誤解をしていたことを理解しましたので、ついでに紹介したいと思います

以下の結果がどうなるか、って分かりますか?

    JAVASCRIPT:
    function Hoge(){}
    Hoge.prototype = {
    aList:["123"]
    ,xList:["456"]
    };

    foo = new Hoge();
    foo.aList = ["789"];
    foo.xList.push("789");
    alert(foo.aList);//789
    alert(foo.xList);//456,789

    bar = new Hoge();
    alert(bar.aList);//???
    alert(bar.xList);//???

正解はbar.aListは「123」 bar.bListは「456,789」と表示されます。

何を勘違いしていたか?

  • prototypeはreadOnlyという誤解

解説書などに見る「暗黙の参照」と言う言葉、読み込み時のみ評価されるという説明で、prototypeプロパティはインスタンスからは書き換えが出来ないと思っていました。

したがって、プロパティの継承が有効なのは、プロパティの値を書き込むときではなく、読み出すときに限られます。プロトタイプからプロパティを継承するオブジェクトoにプロパティpを設定すると、新しいプロパティpが生成され、オブジェクトoに直接格納されます。(JavaScript第5版 P155 9.2 プロトタイプと継承)

「書き換えが出来る」ってわけではない

    JAVASCRIPT:
    function Hoge(){}
    Hoge.prototype = {
    aNum:1
    ,xNum:10
    };

    foo = new Hoge();
    foo.aNum = 2;
    foo.xNum++;
    alert(foo.aNum);//2
    alert(foo.xNum);//11

    bar = new Hoge();
    alert(bar.aNum);//??
    alert(bar.xNum);//??

とした場合、aNumは「1」、xNumは「10」です。
直接値を操作しようとしている(xNum++)のに値はprototypeのままです。

つまり、prototypeプロパティのプロパティでプリミティブ値ではないものは参照渡ししてるってこと?

    JAVASCRIPT:
    function Hoge(){}
    Hoge.prototype = {
    aObject:{a:"a"}
    ,xObject:{}
    };

    foo = new Hoge();
    foo.aObject.a="aa";
    foo.xObject.x="x";
    alert(foo.aObject.a);//aa
    alert(foo.xObject.x);//x

    bar = new Hoge();
    alert(bar.aObject.a);//aa
    alert(bar.xObject.x);//x

    やっぱり。
    prototypeのプロパティがプリミティブ値かどうかで判断しているっぽい。かな。

コピーはされてるのか?

    JAVASCRIPT:
    function Hoge(){}
    Hoge.prototype = {
    aNum:1
    ,xList:[]
    };

    foo = new Hoge();
    foo.aNum++;
    foo.xList.push("123");

    alert( foo.hasOwnProperty("aNum") ); // true
    alert( foo.hasOwnProperty("xList") ); // false

    コピーされていない!

結局どういうことかというと、

  1. prototypeプロパティのプロパティがプリミティブ値であった場合、プロパティのコピーが行われ、処理は元オブジェクトに対してのみ行われる
  2. prototypeプロパティがプリミティブ値でなかった場合、プロパティのコピーが行われず、処理はprototypeプロパティに対してのみ行われる。

JavaScriptはまだまだ奥が深いです。

この記事へのコメント: 0件

コメントをどうぞ
上記情報を記憶する(次回から入力の手間が省けます)

トラックバック+ピンバック: 0件

Home > 未分類 > javascriptのprototypeプロパティでハマった

ページ
メタ情報

Page Top