Posted at

Node.jsにおけるthisの値の違い


はじめに

コードを書いている中で、 this を度々使っているでしょう。

そのときちゃんと this の値を意識できていますか?

その値の違いをまとめていきます。


参考資料


thisの値


無名関数内

thisの値はレシーバ(左辺)の親になる。

もしもレシーバが存在しない場合は、グローバル( Object [global] )となる。


main.js

function Test() {

this.field = 'test';
};
Test.prototype.func = function() {
console.log(this);
};

const test = new Test();
test.func();


$ node ./main.js

Test { field: 'test' }


アロー関数内

thisの値はその関数のスコープ内のthisと同じになる。

もしもグローバルスコープで宣言された場合は、空オブジェクト( {} )となる。


main.js

function Test() {

this.field = 'test';
};
Test.prototype.func = () => {
console.log(this);
};

const test = new Test();
test.func();


$ node ./main.js

{}


クラスのメソッドの中で定義された関数内(ES2015以降の書き方)

無名関数で書いた場合、thisの値はクラスのメソッドの親のスコープとなり、 undefined が返る。

一方アロー関数で書いた場合、thisの値はクラスのメソッドのスコープとなり、 Test が返る。


main.js

class Test {

test() {
this.one = '111';
callback(function() {
console.log('anonymous:', this);
});
callback(() => {
console.log('arrow :', this);
});
}
}

const test = new Test();
test.test();

function callback(func) {
func();
}


$ node ./main.js

anonymous: undefined
arrow : Test { one: '111' }


クラスのメソッドの中で定義された関数内(ES2015以前の書き方)

無名関数で書いた場合、thisの値はクラスのメソッドの親のスコープとなり、 Object [global] が返る。 ES2015以降の書き方を使った場合とは異なる動作をする。

一方アロー関数で書いた場合、thisの値はクラスのメソッドのスコープとなり、 Test が返る。


main.js

function Test() {};

Test.prototype.test = function() {
callback(function() {
console.log('anonymous:', this);
});
callback(() => {
console.log('arrow :', this);
});
};

const test = new Test();
test.test();

function callback(func) {
func();
}


$ node ./main.js

anonymous: Object [global] { ... }
arrow : Test { one: '111' }


おわりに

this の内容は、使う場所によって異なります。

そのため、動作をしっかりと押さえておかないと、正しく動作するプログラムを作れません。

よくあるケースとして、こんなものがあることでしょう。

無名関数で記述しているところを一斉にアロー関数に書き換えます。すると、動作しなくなりました。

こういう問題にぶち当たったときは、一度 this の値に注目してデバッグしてみてください。