jsでクラスを使っているときに出会った現象。他の言語のクラスとは考え方が違ってだいぶ遠回りしましたが、なんとか理解。メモとして残しておきます。
uncaught referenceerrorが出ていて、調べてみるとクラス内変数が思ったように参照できていない様子。
※js歴浅いのであまり自信はありません。他のプログラマーさんの情報も参考にしてください。
class構文にてインスタンス変数を準備する
jsでクラスを使うときにクラス内変数を使うなら以下のようにする必要があります。
class TestClass {
constructor() {
this.valueA = "値1";
this.valueB = "値2";
}
}
一般的なオブジェクト指向言語で学習済みな人だと混乱するところですが、jsの場合クラス内にはメソッドしか存在できません。※staticなプロパティは可。
その代わり、this.~~~という変数に値を与えると、それがクラス内変数のような振る舞いを取ります。
なので、constructorの中で設定してしまおうというのがお決まりな様子。
thisは状況によって変わってしまう!
今回、このthisが変わってしまっているパターンがあったのが困ったところ。他の言語ならthisが変わるってなかなか考えられませんよね?
jsならこういったパターンの時、thisは変わってしまいます。
//ダメパターン
class TestClass {
constructor() {
this.valueA = "値1";
this.valueB = "値2";
let target = document.getElementById("id");
target.onclick = function() {
alert(this.valueA); ←注意!!!!!!
}
}
}
実はfunction(){ }の中では、thisがfunctionにスコープ遷移してしまうので、TestClassのインスタンス変数にアクセスできなくなってしまうのです。これがclassでなければvar selfにthisを保管しておくのが慣例みたいですが、classの時にはできません。
ではどうするのかと言うと。。。
ラムダで処理を記述する
functionを使うとthisは変わってしまうので、ラムダ式(アロー関数)を使って定義し直しましょう。
//正解パターン
class TestClass {
constructor() {
this.valueA = "値1";
this.valueB = "値2";
let target = document.getElementById("id");
target.onclick = () => {
alert(this.valueA);
}
}
}
こうするとthisはTestClassインスタンスを差したままになるので、意図した使い方が出来るかと思います。