項目69 コールバックのthisがAPIの一部なら、それに型を与える
JavaScriptのthisはスコープが動的
letやconstはレキシカルスコープをもつが、thisのスコープは動的でその値は使われ方の文脈に依存する 特にクラスで使われる
JavaScriptのthisへのバインドについて
code:js
class C {
logSquares() {
for (const val of this.vals) {
console.log(val ** 2);
}
}
}
const c = new C();
c.logSquares;
上記のc.logSquares()実行時に、JavaScriptは以下のことを行っている
C.prototype.logSquaresを呼び出す
thisをcにバインドする
下記のコードは、logSquaresへの参照を取り出したことで、thisへのcのバインドが行われずエラーになる
code:js
const c = new C();
const method = c.logSquares;
method(); // thisがundefinedになりエラー
後からthisにバインドをしたい際はcallを使う
code:js
const c = new C();
const method = c.logSquares;
method.call(c); // OK
コールバックのthisがAPIの一部なら、それに型を与える
コールバックにthisをバインドしているなら、それはAPIの一部なので型宣言に含める
code:ts
function addKeyListener(
el: HTMLElement,
listener: (this: HTMLElement, e: KeyboardEvent) => void
) {
el.addEventListener('keydown', e => listener.call(el, e));
}
コールバックのthisパラメータは特別で、暗黙的に引数が渡されるのでパラメータが増えるわけでなない
code:ts
function addKeyListener(
el: HTMLElement,
listener: (this: HTMLElement, e: KeyboardEvent) => void
) {
el.addEventListener('keydown', e => {
listener(el, e);
// ~ Expected 1 arguments, but got 2
// 1 個の引数が必要ですが、2 個指定されました。
});
}
新しいAPIを設計する際は、動的なthisのバインドはつかわないようにする