this についての理解(1)
前回の記事で自分が次になにをすべきか確認したので早速thisからとりかかりました。
( ・∇・)!
日本語の記事でわかりやすかったのはこちら。
takkyunさんという方の記事です。takkyun - Qiita
英語はこれがわかりやすかった。
Understanding Binding and 'this' in Javascript · GitHub
youtubeだとこちらわかりやすかったです。(英語)
WTF is THIS: Understanding the "this" keyword in JavaScript
thisのvalueは、シチュエーションによって変わるそうです。
( ・∇・)
ひとつめ。
Implicit Binding: dot notation is used to invoke a function
関数実行時に「 . (ドット) 」がつかわれるパターン
→ 「 . (ドット) 」の左側にあるものがthisのvalueになる。
先ほど紹介した英語の記事では
In implicit binding, whatever is to the left of the dot becomes the context for
this
in the function.
と大胆に書かれています。
dot notation で関数が呼ばれその中にthisがはいっているときはこのパターン。
冒頭で紹介したtakkyunさんの記事では、「this と function の関係」という章で書かれています。
サンプルコードをのせておきます。
例1
( ・∇・)
次。
Explicit Binding:
関数実行時に.call( ), .apply( ), or .bind( )のいずれかが使われている場合。
これらは関数のメソッドです。
→ .call( ), .apply( ), .bind( )のカッコ内にある引数がthisのvalueになります。
callとapplyの違いは、
call はargument listを受け入れるのに対して、applyは一つのarrayを受け入れる点だそうです。
Note: While the syntax of this function is almost identical to that of
call()
, the fundamental difference is thatcall()
accepts an argument list, whileapply()
accepts a single array of arguments.
冒頭で紹介したYouTubeの06:40以降でわかりやすく解説されています。
( ・∇・)
関数実行時に、別スコープにあるオブジェクトの情報をつかいたい。
そんな時にこの方法をつかうんですね。
explicit は明確にとか率直にという意味なので、
使いたいオブジェクトを明確に引数として渡す、みたいなイメージなのかもしれませんね。
サンプルコードです。
先ほどは、オブジェクト内のメソッドとしてfunctionが存在していましたが、今回は外側にあります。
例2
ここで仮に、先ほどと同様に、student1.sayHello(); と関数を呼び出してみたとします。
Uncaught TypeError: student1.sayHello is not a function
( ・∇・)?
エラーになりました。
sayHelloはfunctionではないと。。
sayHelloはfunctionで一番頭で宣言してるんですけど。。。
ただしい表現ではないかもしれないのですが、
student1.sayHello();というのは、student1のsayHelloを実行してという指示になります。
例2のコードをみていただくとstudent1 はメソッドをもっておりません。
なのでstudent1の中にsayHelloは存在していないため、エラーになるという理解を私はしました。
では、どうやったらsayHelloを実行できるのかとなりますが、
ここでメソッドをつかうんですね。
( ・∇・)!
call をapply に変えても、この例の場合は同じ結果でした。
このときのthisは、引数として渡されたオブジェクトになってますね。
そして、.bind() ですが、これはちょっとややこしく、 .call()とほぼ同じなのですが、新しい関数を返してくるものになるそうです。
( ・∇・)?
では試しに、先ほど試したcallをそのままbindに変更してみます。
何もコンソールに表示されません。
エラーもなしです。
( ・∇・)?
無理やりコンソールしてみました。
t
たしかに新しい関数になっています。
関数なので実行には()が必要ですよね。
ということでこちらで試してみます。
これはどうなるでしょう?
( ・∇・)
ででーん!
いけましたね。
ちなみに、多くの場合は変数に代入して使うみたいです。
実行結果は同じです。
最後です。
thisにはデフォルトがあるらしいです。
Default Binding:
thisを含む関数を実行するけれども、dot notation もつかわず、call(), apply(), bind()もつかっていないとき。
→ デフォルトでWindowオブジェクトがthisのvalue。もしstrict modeが適用されているなら、undefined。
ためしにコンソールでthisとうってみました。
( ・∇・)!
これがめちゃくちゃわかりやすいので、そのままはっておきます。
- Is there a dot? Look to the left. That's
this
.- Do you see .call() or .apply()? What's passed in before the first comma? Thats
this
.- Does the function stand alone when it's invoked? Then what's your global context? That's
this
.
だいぶ長くなりました。
読んでいただきありがとうございます。