javascriptでメソッドからメソッドを呼び出した時に自身のオブジェクトを表すthisが使えない
ものすごい長いタイトルになりましたが、これでハマってたので書いておきます。
大切なのはjavaの"this"とjavascriptの"this"は同じだと思うなってことです。
javaでクラスを書くとこんな感じです
class A {
int x;
void methodA() {
this.x=10;
methodB();
}
void methodB() {
this.x=20;
}
}
この定義からインスタンスを生成してからmethodAを呼び出すと、methodAもmethodBもthis.xはAで定義されているメンバ変数 x を指すので、x は20になるはずです。
javascriptで似たようなことを実装するつもりで、以下のサイトを参考に作りました。
以下のようなコードを作りました。
var A = (function() {
var A = function() { //コンストラクタ
this.x=0; // これがクラスのメンバ変数になる
}
var p = A.prototype;
// 以下がメソッド
p.methodA = function() {
this.x=10; // これはクラスのメンバ変数を参照して代入される
p.methodB();
};
p.methodB= function() {
this.x=20; // これが想定通りに動かない
};
})();
javaと同様にインスタンスを生成してmethodAを呼び出しても 20 にはなりません。
methodB内の this.x はメンバ変数を指さないようです。これにしばらくはまっていました。
いろいろ調べてみると以下のサイトに詳しく書かれていました。
call メソッドを使う必要があるとのこと。
var A = (function() {
var A = function() {
this.x=0; // これがクラスのメンバ変数になる
}
var p = A.prototype;
// 以下がメソッド
p.methodA = function() {
this.x=10; // これはクラスのメンバ変数を参照して代入される
p.methodB.call(this); //親になるオブジェクトを引数に指定
//この時点でのthisはクラスのオブジェクト
};
p.methodB= function() {
this.x=20; // callで呼ばれると指定したオブジェクトを参照できる
};
})();
これで解決できるようですね。methodAが呼ばれた後、最終的にメンバ変数xが20になるはずです。