thisが指し示すもの
thisを直訳すると“これ”ですよね。
テーブルの上に置かれた本を指差しながら、”This is my book.”と言う時などに使われます。
つまり【This=これ】とは、自分のすぐ近くに存在するものを指し示す時に使う言葉であるということになります。
そして、プログラミングにおけるthisもそのような考え方でOKです。
thisはオブジェクトやクラスの中で用いられますが、thisはオブジェクトやインスタンス化されたオブジェクト自身を指し示すという役割を持ちます。
最も簡単な例をみてみましょう。
オブジェクトの中にthisをログで表示させる関数を値として入れておき、オブジェクトを定数に格納します。(分かりやすくするため、ついでにnameプロパティも入れておきました)
そして関数を実行してみると…?
JavaScript
const obj = {
name: 'thisをテストするオブジェクト',
test: function() {
console.log(this);
}
}
obj.test();
表示結果(コンソール画面)は次のようになります。
表示結果
コンソールに表示された内容から、thisが自身が属するオブジェクト(obj)を指し示していることがわかりますね。
当然、console.log(this)をconsole.log(this.name)とすれば、nameプロパティの値を参照できます。
JavaScript
const obj = {
name: 'thisをテストするオブジェクト',
test: function() {
console.log(this.name);
}
}
obj.test();
表示結果
このように、まずはオブジェクトのthisはオブジェクト自身を指し示すという基本を覚えておくことがthisをマスターするための第一歩となります。
POINT!
- ・オブジェクト内のthisは、オブジェクト自身を指し示す!
- ・this.プロパティ名で、オブジェクトのプロパティも参照可能!
- ・まずはオブジェクト内のthisを理解しよう!
クラスの中で使われるthis
thisはオブジェクトだけでなく、クラスの中でもオブジェクトと同じように扱われます。
クラスとはオブジェクトを生成するテンプレートです。
クラスについてまだよく分かっていないという方は、クラス=様々な変数やメソッドを含む再利用可能なプログラムの塊…みたいなイメージを持っておくと良いでしょう。
クラスの中で使われるthisは、インスタンス化されたオブジェクト自身を指し示します。
下のサンプルコードをご覧ください。
MyClassと宣言したクラスの中で、コンストラクタ(インスタンス化された時に呼ばれる)に、this.name = ‘鈴木’と指定しました。
thisはクラス自身を指すので、クラスがインスタンス化された時に作られるオブジェクトのnameプロパティに’鈴木’という値が入ることになります。
また、displayName()というメソッドを作り、this、this.nameをログに表示させて確認できるようにしました。
そしてこの時、this=インスタンス化されたオブジェクト自身であるということを確認するため、thisとインスタンス化したものを格納した定数を厳密等価(===)でチェックし、同一であればtrueを返すようにしています。
JavaScript
class MyClass {
constructor() {
this.name = '鈴木'
}
displayName() {
console.log(this);
console.log(this.name);
console.log(this === myClass);
}
}
const myClass = new MyClass();
myClass.displayName();
表示結果
thisがインスタンス化されたオブジェクト自身を指していることが、コンソール画面から確認できました。
基本的にはこのように、this=オブジェクト自身を指し示すという認識で問題ありません。
しかし、関数の中で使われるthisに関しては少し注意が必要です。
次の章では、通常の書き方による関数でthisを参照した場合と、アロー関数を使った関数でthisを参照した場合の違いについて確認していきましょう!
POINT!
- ・クラスの中のthisはインスタンス化されたオブジェクト自身を指し示す!
- ・挙動としてはオブジェクト内のthisと同じ!
- ・関数の中で使われるthisは違う挙動になることも(詳細は次の章で)!
関数の中で使われるthis
オブジェクトには関数をプロパティの値として入れておくこともできますが、その関数の中でさらに関数を宣言して実行することが可能です。
ところで、JavaScriptにおいては関数は大きく分けて2つの書き方があります。
1つは、function 関数名(引数) { 処理の内容 }…というような、これまでの通常の書き方。
そしてもう1つは、 定数(変数) 関数名 = (引数) => { 処理の内容 }…というような、アロー関数と呼ばれる書き方です。
無名関数にする場合や引数の数によって関数の書き方が変わる場合もありますが、基本的には上の形になると覚えておいて問題はありません。
ここでは、アロー関数に対してfunction+関数名で記述する関数を通常の関数と呼ぶことにしたいと思います。
thisはオブジェクト自身を指し示すと述べましたが、通常の関数でthisを参照するとwindowオブジェクトを指してしまいます。
この挙動はプログラマにとってやや不自然に感じられる挙動でしょう。
そのため、関数の中でthisを使う場合はアロー関数の方が分かりやすくておすすめです。
下はオブジェクトに格納した関数内に通常の関数とアロー関数を格納し、実行してコンソール画面に結果を表示させたものです。
コードと表示結果を見比べながら、thisが指し示すものを確認してみてください。
JavaScript
const obj = {
name: '鈴木',
functions:
function() {
const arrow = () => {
console.log(this);
}
function normal() {
console.log(this);
}
arrow();
normal();
}
}
obj.functions();
表示結果
通常の関数(normal()で実行)の方では、Windowオブジェクトを指し示しているのが分かります。
一方、アロー関数(arrow()で実行)の方では、これまでの解説通りオブジェクト自身を指し示しています。
POINT!
- ・関数は大きく分けて2通りの書き方がある!
- ・通常の関数でthisを使うとWindowオブジェクトを指し示してしまう!
- ・アロー関数でthisを使うとオブジェクト自身を指し示す!
まとめ
今回の記事のまとめです。
- thisが指し示すもの
- オブジェクトやインスタンス化されたオブジェクト自身
- 通常の関数では
- function 関数名(引数) { }…といった関数でthisを参照するとWindowオブジェクトを返す
- アロー関数では
- const 関数名 = () => { }…といった関数でthisを参照するとオブジェクト自身を返す
thisをちゃんと理解できると、オブジェクトやクラスがグンと扱いやすくなります。
また、オブジェクト指向に慣れておくと他のプログラミング言語も学びやすくなるので、基礎的かつ根本的なところをしっかりと押さえておきましょう!