0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

ES6でのthisについて

Last updated at Posted at 2020-09-02

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())
0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?