しまてく

学んだ技術を書きためるブログ

new演算子とthisキーワード

3/20に書いたエントリに対する追考

id:GegegeMokekeコメントで宿題をもらったので早速試してみました。

↓こんな感じのテストコードで試しました。

var p,q; // 確認用
function hoge(){
}
hoge.moge = function(){
    p = this; // ここのthisが知りたい
}
hoge.moge.prototype = {
    piyo: function(){
        q = this;
    }
};

// そのまま呼び出してみる
hoge.moge(); // this は hoge そのもの
// 確認
alert( p == hoge ); //true 

// new で呼び出してみる
var a = new hoge.moge(); // this は hoge.moge のインスタンス
// 確認
alert( p instanceof hoge.moge ); // true
alert( a == p ); // true
alert( a.constructor == hoge.moge ); // false ※後述

// 更に hoge.moge の prototype プロパティの関数をnew してみた
var b = new a.piyo(); // this は hoge.moge.piyo のインスタンス
// 確認
alert( q instanceof a.piyo ); // true
alert( b == q ); // true
気づいたこと

new についての理解が浅かった><
サイ本を読み直すと以下のようなことが書いてありました。

    1. new演算子はまずプロパティを定義せずに新しいオブジェクトを生成する。
    2. 指定されたコンストラクタ関数のprototypeプロパティの値をオブジェクトのプロトタイプに設定する。
    3. 次に指定されたコンストラクタ関数を呼び出し、指定された引数を渡す。
    4. 同時に、新たに生成されたオブジェクトをthisキーワードに代入して渡す。
    5. new演算子で指定するコンストラクタ関数は、何もreturnしなければthisが返る。
    6. コンストラクタ関数で何かをreturnすると、(4)で生成されたオブジェクトは破棄される。

(2)の実際の動きは分かるんだけど、インタプリタの中の人は
「このプロパティはコンストラクタのprototypeプロパティだよ」って判断を
どうやってしてるのかが分かりません。。


始めはオブジェクトのconstructorプロパティをみてるのかと思ったんですけど
上の例みたいに prototypeプロパティ を上書きしてしまうと prototypeプロパティの中の
constructorプロパティが消えるハズ。(「a.constructor == hoge.moge」が false になる)
でも「a instanceof hoge.moge」は trueになる。。う〜・・・

分からないこと
    • constructorプロパティって何者なんでしょう??(何のためにあるのか?)
    • どうやってクラスのprototypeプロパティを参照してるのか?(内部的に実はポインタ持ってる?)


詳しい人ヒントくだしあ><