ES6から追加になったアロー関数ですが、もちろん短く完結に書けるという点で便利なのですが、
他にもES5でよく悩まされたthisの扱いでも便利な点があることに気付いたため試してみます。
ES5でのthis
以下のようなコールバック関数でthisを使うとします。
※ 後で気付いたのですが、constはES6以降なので純粋にES5で実行するにはvarですね。他にもテンプレートリテラルもないでしょ、とか本題と関係ないところはおいておきます。
aboutthis.js
const team = {
members: ['太郎', '花子'],
teamName: 'Aチーム',
teamSummary: function() {
return this.members.map(function(member) {
return `${member}は${this.teamName}の所属です。`
})
}
}
console.log(team.teamSummary())
実行結果]
$ node aboutthis.js
[ '太郎はundefinedの所属です。', '花子はundefinedの所属です。' ]
よくある勘違いなのですが、thisは'team'ではなく、'undefined'になってしまうわけです。
これを解消するためによくやるのはthisを変数に取っておくこと。もう一つはbindでthisを束縛するやり方。
解決法その1 thisを変数に取っておく
index.js
const team = {
members: ['太郎', '花子'],
teamName: 'Aチーム',
teamSummary: function() {
var self = this //ここでthisを変数にとっておき
return this.members.map(function(member) {
return `${member}は${self.teamName}の所属です。` //ここで使う
})
}
}
console.log(team.teamSummary())
実行結果]
$ node aboutthis.js
[ '太郎はAチームの所属です。', '花子はAチームの所属です。' ]
無事、所属が出力されました。
解決方法その2 bindでthisを束縛する
index.js
const team = {
members: ['太郎', '花子'],
teamName: 'Aチーム',
teamSummary: function() {
return this.members.map(function(member) {
return `${member}は${this.teamName}の所属です。`
}.bind(this))
}
}
console.log(team.teamSummary())
実行結果]
$ node aboutthis.js
[ '太郎はAチームの所属です。', '花子はAチームの所属です。' ]
さっきよりはすっきりしました。
ES6では? アロー関数
最初の状態に戻し、コールバック関数をアロー関数に変えてみます。
index.js
const team = {
members: ['太郎', '花子'],
teamName: 'Aチーム',
teamSummary: function() {
return this.members.map((member) => {
return `${member}は${this.teamName}の所属です。`
})
}
}
console.log(team.teamSummary())
実行結果]
$ node aboutthis.js
[ '太郎はAチームの所属です。', '花子はAチームの所属です。' ]
するとあら不思議、所属がちゃんと取得できてます。
アロー関数にするとthisが呼び出し元と一緒になるんですね。
レキシカル(lexical)thisといいます。
最後に
lexical thisとは関係ない話ですが、今回の例題はもっとすっきり以下のように書けます。
index.js
const team = {
members: ['太郎', '花子'],
teamName: 'Aチーム',
teamSummary: function() {
return this.members.map(member => `${member}は${this.teamName}の所属です。`)
}
}
console.log(team.teamSummary())