[ECMAScript6]callback関数内のthisのスコープについて
2017.06.22
こんにちは、ユニトラストの宮本です。
業務でECMAScript6に触れる機会があり、ちょっとしたつまずきポイントの備忘録です。
そもそもECMAScriptって?
JavaScript(NetScape社)とJScript(Microsoft社)が微妙に動作が異なっていたのでそれを統一させるために作られたものが、JavaScriptの標準規格である「ECMAScript」です。
年々新たな仕様が追加されて、classを使える等色々なことができるようになってきています。
トランスパイラについて
トランスパイラとは、ECMAScript6からECMAScript5の形式へ変換するツールのことです。
実はECMAScript6はこのままだとまだ使えないブラウザがあります。
なので、すべてのブラウザで使えるようにECMAScript6からECMAScript5の形式へ変換してあげる必要があります。
その時に使うのがトランスパイラです。
Babelやbubleなど様々あるので開発に合わせてチョイスしてください。
アロー関数内のthisのスコープについて
ECMAScript6からアロー関数が使えるようになりました。
例えば、今まで
//今までの無名関数 var double = function(i) { return i * 2; }
こう書いていたものが
//アローを使った無名関数 var double = (i) => { return i * 2; }
こう書くことができるようになりました。
アロー関数の最大の利点はthisを拘束できる所にあります。
今までだと
global.prop = 'これはグローバルプロパティです。'; let obj = { prop: 'これはobjのプロパティです。', func: function(){ console.log(this.prop); // これはobjのプロパティです。 (function(){ console.log(this.prop); // これはグローバルプロパティです。 })(); } }; obj.func();
このように関数の中で関数を呼ぶとなぜかグローバルのオブジェクトを指してしまう仕様でした。。
これをアロー関数で書くと
global.prop = 'これはグローバルプロパティです。'; let obj = { prop: 'これはobjのプロパティです。', func: function(){ console.log(this.prop); // これはobjのプロパティです。 (()=>{ console.log(this.prop); // これはobjのプロパティです。 })(); } }; obj.func();
関数の中の関数であってもthisを拘束することができます。
実際のつまずきポイント
ある関数を引数に渡して受け取った関数内で実行しようと
class example { function method(callback) { callback(); // undefinedになってしまう。。 } } class test { function result() { // 処理 } this.example.method(this.result); }
と書いたところ、受け取った関数内でundefinedとなってしまった。。。
なぜなのか?
引数で渡した関数のthis.resultのスコープが元のクラス内ではなく、先のクラス内を見ている為、見つからずにundefinedになってしまっていることが原因でした。。
this.resultのthisがキチンと拘束出来ておらず、resultという関数を見つけられなかったのです。。
解決策
callbackをアロー関数で渡す
関数を渡す時にアロー関数を用いて渡してあげることで、thisを拘束することができます。
this.example.method(() => { this.result(); }); // こう書くことでthisを拘束できる
少しクセのある書き方になってしまいますが、覚えておくと便利です。
CONTACT
お問い合わせ
あなたの「想い」に挑戦します。
どうぞお気軽にお問い合わせください。
受付時間:平日9:00〜18:00 日・祝日・弊社指定休業日は除く