47
80

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の闇... thisについて、様々な角度で挑みたいと思います!

【YouTube動画】JavaScriptの闇 this
JavaScriptの闇 this

thisとは

thisは関数の呼び出し元へのリンクです。

例えば、以下の場合test.getName()はtaroを返します。

thisは関数getNameで呼び出されています。その関数getNameはtestオブジェクトの関数なので、this = testオブジェクトになります。
関数getName()のthisをtestオブジェクトに変え、test.name = taroとなります。

const test = {
  name: 'taro',
  getName: function() {
    return this.name;
  }
}

グローバルなthis

関数の読み出し元を指定しない場合はWindowになります。
それを確認してみましょう。

以下2つを定義しておきます。

まず、obj.sayThis()を考えます。
sayThis()はobjオブジェクトから呼び出されているので、関数sayThis内のthisはobjオブジェクトになります。
ということで、obj.sayThis()は { name: 'taro' } を返します

次に、sayThis()を考えます。
こちらは特に呼び出しているオブジェクトがないため、Windowになります。
ちなみに、strictモードで実行すると、undefinedになります。

// メソッド
const sayThis = function() { console.log(this) }

// オブジェクト
const obj = { name: 'taro' }

コンストラクタでのthis

コンストラクタではnewでオブジェクトを作成でき、呼び出し元が定まります。

以下のように定義しておきます。

yamadaの方ではnew Personによりオブジェクトが作成されるので、yamada.nameはtaroを返します。
しかし、tanakaの方はオブジェクトが作成されていないので、name of undefinedエラーになります。

const Person = function(hoge) { this.name = hoge; }

const yamada = new Person('taro')
const tanaka = Person('taro')

プロトタイプメソッド内でのthis

以下のように定義しておきます。
ここで、yamada.getName()とすると、taroが返ります。
ちなみに、Person.getName()の場合はPerson.getName is not a functionになります。

const Person = function(hoge) { this.name = hoge; }
Person.prototype.getName = function() { return this.name; }

const yamada = new Person('taro')

対して、次のようにprototypeをなくした場合は、yamada.getName is not a functionになります。
また、Person.getName()の場合、Personが返ります。

const Person = function(hoge) { this.name = hoge; }
Person.getName = function() { return this.name }

const yamada = new Person('taro')

入れ子関数でのthis

入れ子関数にすると、定義元はどうなるでしょう。

以下を定義して、test.sayHello()を実行すると、上から { sayHello: f }, Windowになります。
最初のthisの呼び出し元はsayHelloで、2番目のthisは呼び出し元が明示されていないためです。

const test = {
  sayHello: function() {
    console.log(this)
    const func = function() {
      console.log(this)
    }
    func()
  }
}

arrow関数でのthis

入れ子関数でもarrow関数にすると、thisの呼び出し元が定まります。

そのため以下の場合、test.sayHello()は、{ sayHello: f }, { sayHello: f } になります。

const test = {
  sayHello: function() {
    console.log(this)
    const func = () => {
      console.log(this)
    }
    func()
  }
}

まとめ

今回はJavaScriptで迷いやすいthisについて解説していきました!
なるほど分からんと思った方、ぜひコンソール画面などで遊んでみてください!

twitteryoutubeでのコメントもお待ちしています!

47
80
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
47
80

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?