ECMAScript6でthisを束縛する方法について
ECMAScript6でthisを束縛する方法について検証した際のメモ
まずダメな例として、以下は画面クリックの際に呼ばれる clickFunc
から this.calledFunc()
を呼び出すことはできません。クリックに反応したelementがthisになるため、この場合はリスナーが設定されたdocumentがthisになりthis.calledFunc()を呼び出すことはできません。
class Application { constructor(){ this.init(); } init() { document.addEventListener('click', this.clickFunc, false); } clickFunc(event) { this.calledFunc(); } calledFunc() { alert("called"); } } const app = new Application();
bindを使う
よく使われる方法としてはbindを使ってthisを束縛する方法があります。今回の場合は以下のようになります。これなら簡単に思った通りになります。
class Application { constructor(){ this.init(); } init() { document.addEventListener('click', this.clickFunc.bind(this), false); } clickFunc(event) { this.calledFunc(); } calledFunc() { alert("called"); } } const app = new Application();
Arrow関数を使う
ECMAScript6から導入されたArrow関数を使うとthisは関数定義時に通常の関数と同じように決まるので、以下でも呼び出すことができます。
class Application { constructor(){ this.init(); } init() { document.addEventListener('click', (event) => {this.clickFunc}, false); } clickFunc(event) { this.calledFunc(); } calledFunc() { alert("called"); } } const app = new Application();
関数の実装を他のクラスに分ける場合
Applicationクラスに関数が増えすぎたなどでclickFunc
の実装を他のファイルに分けたい場合, thisのさす先が変わるのでそのままではApplicationに割り当てられた関数を利用することができません。その場合は以下のように束縛対象にObjectを渡すことで想定した動きにできます。
test-func.js
export function clickFuncGen(app) { const func = (event) => { app.calledFunc(); } return func; }
index.js
import * as T from './test-func'; class Application { constructor(){ this.init(); } init() { this.clickFunc = T.clickFuncGen(this); document.addEventListener('click', this.clickFunc, false); } } const app = new Application();