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 5 years have passed since last update.

javascriptのthisの扱いについて

Last updated at Posted at 2017-10-16

備忘録的なメモです。
間違いがある可能性がありますので、ご注意ください。
その際は指摘いただけるとありがたいです。

Javascriptにおけるthisの扱いは注意が必要になる。
thisの対象になるのはそのthisが実行されるコードに依存するという原則がある。thisはそれを呼び出したオブジェクトに依存する。

つまり、thisを持ったオブジェクトをどこで宣言しようと、最終的にはそれが実行されたコードにthisの参照先が設定されるということである。このことを理解しないととんでもないバグを生む可能性がある。

また、自分がよく混同するのが「this」と「関数のスコープ」である。thisはそれが定義された場所によらず、それが実行された文脈によって設定されるが、関数のスコープ(クロージャ的な使われ方)ではそれが定義された場所でスコープが決定する。

   function test() {
        this.title = 'test';
        this.inner = function() {
            alert(this.title);
        }
    };

    var _test = new test();
    setTimeout(_test.inner, 3000)

このようなコードではsetTimeoutに渡したinnerメソッドのthisはsetTimeoutのthisに依存するため、 undefindが表示されてしまう。ここでの動きに注意。

ここの処理ではコールバックにメソッドを渡しているが、setTimeoutのコールバックの渡し方を変える

setTimeout(_test.inner(), 3000)

ここでの、_test.inner()では関数呼び出しを行っているのでコールバックに渡している段階で、
処理が実行されているということ。この場合のthisは_testオブジェクトを参照している。
これは処理で言えば、

_test.inner();

これと同じ。
なので、setTimeoutが評価された段階で、alertが表示される。

func.bind() を使うことで、thisの対象を固定することができる

setTimeout(_test.inner.bind(_test), 3000)

_test.innerメソッドに対してthisを自分自身にbindする。
つまり

<<<<<<< HEAD

thisを固定させたいオブジェクト.bind(固定するオブジェクト)
=======
```js
Thisを固定させたいオブジェクト.bind(固定するオブジェクト)
>>>>>>> EDIT_REQUEST

という構文になる

thisの固定はbind以外にもcallとapplyがある。
両者の使い分けはcallとapplyが指定したオブジェクトでthisを固定して、関数を実行する。
Bindは指定したオブジェクトでthisを固定して新しい関数を生成する
という違いにある。繰り返し使う必要があるなら、bindを使った方がいい。

0
1
1

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?