対象読者
- JavaScriptのオブジェクトについて理解している初学者
- thisの挙動がいまいちわからないJavaScript初学者
そもそもJavaScriptにおけるthisって何?
JavaScriptにおけるthisとは、自分自身を表すオブジェクトのことを挿します。重要なポイントは呼び出し元によって変わる点です。どういうことか以下に記載していきます。
グローバルオブジェクトを指すthis
const sayFoo = function () {
console.log(this["foo"]);
}
foo = "foo";// 予約後であるconst,letをつけない場合はグローバルオブジェクトとして定義される
sayFoo();
sayFoo.js
では、sayFoo()を呼び出した場合、グローバルオブジェクト(window
オブジェクト)として変数fooを宣言しています。よって、thisの対象はグローバルオブジェクトをさす挙動になっています。
※this["foo"]
の[]で書く方法はブラケット表記法と呼ばれる書き方です。
ブラケット表記法
#インスタンス変数を指すthis①
const sayFoo = function () {
console.log(this["foo"]);
}
foo = 'foo';
const sayFooInstance = {
foo: "I'm Instance Object",
sayFoo
}
sayFooInstance.sayFoo();
sayFooInstance.js
では、sayFooInstanceオブジェクトにて関数sayFoo
を呼び出しています。sayFooInstance
内部からの呼び出しなので、this["foo"]
はfoo: "I'm Instance Object"
を参照しています。
#インスタンス変数を指すthis②
function MyObj(id) {
this.id = id;
}
MyObj.prototype.printId = function (id) {
console.log(this.id);
}
const newMyObj = new MyObj(5);
newMyObj.printId(2);// MyObjでidをthisに入れているため、2ではなく5と表示される
オブジェクトのプロトタイプに関数を定義して、実行しても、2が表示されず、5が表示されます。
なぜなら、MyObj関数をnewを使ってインスタンス化する際にthis.id = id
で変数idをMyObj関数に代入しているため、printId
が実行されても、this.id
の値に代入されないので、実行結果が5と表示されます。
ちなみに以下の様にClassを使っても同じ形になります。
#インスタンス変数を指すthis③
class MyClass {
constructor(id) {
this.id = id;
}
print(id) {
console.log(this.id);
}
}
const myClass = new MyClass(5);
myClass.print(3);
コンストラクターを使ってインスタンス生成時にthis.idの値を代入します。
インスタンス変数を指すthis②でご紹介した通り、インスタンス生成時にthis.id
にid値を代入しているため、実行結果は5と表示されます。
クラスについてはMDN Web docに記載があります。
クラス MDN Web doc
ちなみに、オブジェクト内部で関数を入れ子にした場合はどうなるでしょうか
インスタンス変数の内部で関数が入れ子になっている場合のthis
const nestFunction = {
nestFunc1: function () {
console.log(this);// nestFunctionを参照
const nestFunc2 = function () {
console.log(this);// グローバルオブジェクトを参照
const nestFunc3 = function () {
console.log(this);// グローバルオブジェクトを参照
}();
}();
}
}
nestFunction.nestFunc1();// 実行
入れ子にした場合のthisは、グローバルオブジェクトを参照します。
ちなみに以下の形{}();
と書かれているコードをみて「ん?」と思った人もいると思います。
以下の書き方は即時実行関数式と呼ばれ、定義されるとすぐに実行されるJavaScriptの関数となります。
const nestFunc3 = function () {
・・・中略・・・
}();// <= 波括弧の隣に丸括弧をつけることで、定義されるとすぐに実行される即時実行関数となります。
MDN Web Docs 用語集 IIFE (即時実行関数式)
thisは理解してしまえば、あとは応用が効く
内容に不備があったり、誤字脱字などあれば、コメントをいただければと思います。