javascript アロー関数のthis は普通の関数のthis とは違う話

ES2015

javascriptって難しいな~ と思う理由の一つに、スコープとか関数の定義の仕方が豊富すぎることがあります。

ある日、アロー関数のthisって普通の関数と違う?と思ったことがあるので書いておきます。アロー関数とは これ => を使った関数定義でfunction とか書かなくてもよい関数の定義の方法です。

   const o = {
       name: 'Hoge Tarou',
       greetName: function (){
           function greetPolite(){
               return 'Hello' + this.name //Helloしか表示されない
           };

           return greetPolite()
       }
   }

   console.log(o.greetName())

上記だと

 greetPolite()

の中で this.name で ‘Hoge Tarou’ を呼べません。

しかし、 下記のようにgreetPolite() をアロー関数にすると、これがthis.name で ‘Hoge Tarou’ を呼べ るんですね~。

   const o = {
       name: 'Hoge Tarou',
       greetName: function (){
           const greetPolite =() => {
               return 'Hello ' + this.name //Hello Hoge Tarouと表示される
           };

           return greetPolite()
       }
   }

   console.log(o.greetName())

アロー関数は他の関数と違い、thisの定義が違うんだそうです。

アロー関数式
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Functions/Arrow_functions

普通は、上記のような関数の中に関数を書いたりはあまりしないと思います💦。
ただ、コールバックとかの中で使う場合はあるのではないでしょうか?

私にとってのきっかけは、この前 axiosを使っていて次のようなところでつまづいたことでした。

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <title></title>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <meta name="robots" content="noindex, nofollow">
    <meta name="googlebot" content="noindex, nofollow">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>

</head>
<body>
<script>
    class Car {
        constructor(type, color) {
            this.type = type
            this.color = color
        }

        setColor(color) {
            this.color = color
        }

        execAxios() {
            axios.get('http://hogehoge.com?param=123')
                .then(function (response) {
                    this.setColor('red')
                }
                )
                .catch(function (error) {
                    //省略
                })
                .then(function () {
                    //省略
                });
        }

    }

    const car = new Car()
    car.execAxios()

</script>
</body>
</html>

上記は

 TypeError: this is undefined 

でエラーになります。(当然っちゃ当然なのですが)
上記のコードの下記の関数を

function (response) {
this.setColor('red')
}

アロー関数にするだけで

response => {
this.setColor('red')
}

this.setColorが呼べてひと段落しましたが、一時なんでアロー関数はOKで、普通の関数がダメなのかがわかりませんでした。

アロー関数とは、関数がはしょって記述できるだけではないんですね。便利に使える局面が多々ありそうです。

上記のアロー関数にした版のコード全文はこちら。

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <title></title>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
    <meta name="robots" content="noindex, nofollow">
    <meta name="googlebot" content="noindex, nofollow">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>

</head>
<body>
<script>
    class Car {
        constructor(type, color) {
            this.type = type
            this.color = color
        }

        setColor(color) {
            this.color = color
        }

        execAxios() {
            axios.get('http://localhost:8080/smart_location_admin/index.php?action=api/driver/getDrivers&company_id=\' + 9841 + \'&branch_id=\' + 10017')
                .then(
                 response => {
                     this.setColor('red')
                     console.log(this) //Object { type: undefined, color: "red" }が表示される
                 }
                )
                .catch(function (error) {
                    //省略
                })
                .then(function () {
                    //省略
                });
        }

    }

    const car = new Car()
    car.execAxios()

</script>
</body>
</html>

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です