1
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.

【JavaScript】JavaScriptの 「this」とは 3 (thisの問題点とアロー関数による解決)

Last updated at Posted at 2020-12-14

※当方駆け出しエンジニアのため、間違っていることも多々あると思いますので、ご了承ください。また、間違いに気付いた方はご一報いただけると幸いです。

こちらは、
【JavaScript】JavaScriptの 「 this」とは 2 (thisの問題点と解決策)
の記事の続きとなります。

##thisの問題点について 2
コールバック関数の中でthisを参照すると問題となる場合があります。

この場合の、対処法としてコールバック関数にアロー関数を使用します。

なぜ、コールバック関数の場合に、thisの参照が問題になるのかというと、コールバック関数内部のthisが呼び出し元を参照するからでした。
実は、この挙動は関数宣言により関数を定義した場合に起こる挙動で、アロー関数は別の挙動をします。

関数宣言の場合、暗黙的な引数として呼び出し元オブジェクトをthisとして受け取るのですが、アロー関数は、thisを受け取りません。

function.js
//関数宣言の場合

human1 = {
  name: "Taro",
  getName: function (x) { //暗黙的に呼び出元オブジェクト(human1)を仮引数xに渡す。(実際には()内は空欄)
  this = x;  //thisにx(human1)を格納。(実際にはこんな式はない)
  }
}
console.log(human1.getName(human1));  //暗黙的に呼び出し元オブジェクトを引数に渡す。実際には()内は空欄
this = x;  //thisにxを格納。

アロー関数には、暗黙的なこの挙動がありません。

下記は、関数宣言でコールバック関数が問題となるコードです。

"use strict";
const prefix = {
  pre: "the",
  addPre(strings) {
    return strings.map(function (str) {
      return this.pre + "-" + str;
    });
  }
};
prefix.addPre(["a", "b", "c"]); 

// =>TypeError: Cannot read property 'pre' of undefined

これをコールバック関数をアロー関数で書き直してみます。

"use strict";
const prefix = {
  pre: "the",
  addPre(strings) {
    return strings.map((str)=> {
      return this.pre + "-" + str;
    });
  }
};
let result = prefix.addPre(["a", "b", "c"]);
console.log(result);

//[ 'the-a', 'the-b', 'the-c' ]

正しく出力されました。

このカラクリを見ていきます。

return strings.map((str)=> {
      return this.pre + "-" + str;
    });

アロー関数が、暗黙的にthisを受け取らないとするならばthisは、一体何を参照するのか。

これは、シンプルに**「this」**という変数として参照します。

当然、アロー関数内に let this = "taro"; みたにな定義文はないので、スコープチェーンを辿って、一つ上の階層へ探しにいきます。

この辺りの挙動は下記の記事を参照してください。

【JavaScript】JavaScriptにおけるクロージャーとは

今、addPre関数は、

prefix.addPre()

のプログラムにより、prefixオブジェクトから呼び出されています。
addPressメソッドの内部自体にはthisがないため、特に意識をしませんが、暗黙的にprefixをオブジェクトを、
thisとして受け取っています。

"use strict";
const prefix = {
  pre: "the",
  addPre(strings, x) { //暗黙的に仮引数xにprefixオブジェクトを格納)
    let this = x; //暗黙的にthisにxを格納。 
    return strings.map((str)=> {
      return this.pre + "-" + str;
    });
  }
};
let result = prefix.addPre(["a", "b", "c"]);
console.log(result);

つまり、アロー関数内のthisは、スコープチェーンを辿って、prefix内の暗黙的なthisを参照するのです。
当然、このthisにはprefixオブジェクトが格納されているので。

アロー関数内のthis.pre は prefix.preを参照し、 「"the"」が取得することができます。

このように、アロー関数を用いることで、意識せずにコールバック関数内のthis問題を解決することができます。

1
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
1
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?