'this'
1. Introduction
I think one of the trickiest parts of JavaScript is 'this' keyword. So, I made this article. I hope this helps you a lot.
In this article, I will use Chrome as a tool. If you use other tools, the result can be different.
2. Not in a Function
2.1. global
|'this'|
console.log(this); // window
A 'this' refers to a 'window'.
|variables and constants in a global scope|
var v = 1;
let l = 1;
const c = 1;
console.log('v', this.v); // v 1
console.log('l', this.l); // l undefined
console.log('c', this.c); // c undefined
A 'var' variable becomes the property of a 'window' unlike 'let' or 'const'.
2.2. in a block
If the block is not a function block, there are no effects.
|in an object|
const o1 = {
k1: this,
};
console.log(o1.k1); // window
|in a method|
※ Let me cover what 'this' refers to in a method later.
const o1 = {
k1: 'v1',
m1(p1) {
if (p1 > 0) {
console.log(this); // {k1: 'v1', m1: ƒ}
}
},
};
o1.m1(7);
2.3. in an object constructor
※ Although it is a function, I put this here because of the structure of this article.
It refers to the instance.
|an object constructor|
function C1(p1) {
this.k1 = p1;
console.log(this); // C1 {k1: 'v1'}
}
const i1 = new C1('v1');
|a constructor in a class|
class C1 {
constructor(p1) {
this.k1 = p1;
console.log(this); // C1 {k1: 'v1'}
}
}
const i1 = new C1('v1');
2.4. in a class field
It refers to the instance.
class C1 {
k1 = 1;
k2 = this;
}
const i1 = new C1();
console.log(i1.k2); // C1 {k1: 1, k2: C1}
3. In a (Regular, Traditional, Normal) Function
3.1. terms
The function refers to a function which is not an arrow function.
Let me call it a 'regular' function from now on.
3.2. conclusion
Let me tell you the conclusion first.
in a method of an object -> the object
in a method of a constructor (I don't know how to call the function exactly. Sorry about that.) -> the instance
other situations -> 'window'
3.3. in a method of an object
It refers to the object.
const o1 = {
k1: 'v1',
m1() {
console.log(this); // {k1: 'v1', m1: ƒ}
},
};
o1.m1();
3.4. in a method of a constructor
※ I don't know how to call the function exactly. Sorry about that.
It refers to the instance.
|function|
function C1() {
this.k1 = 'v1';
this.m1 = function () {
console.log(this); // C1 {k1: 'v1', m1: ƒ}
};
}
const o1 = new C1();
o1.m1();
|class|
class C1 {
constructor() {
this.k1 = 'v1';
this.m1 = function () {
console.log(this); // C1 {k1: 'v1', m1: ƒ}
};
}
}
const o1 = new C1();
o1.m1();
3.5. in a prototype method of a constructor
※ I don't know how to call the function exactly. Sorry about that.
It refers to the instance.
|function|
function C1() {
this.k1 = 'v1';
}
C1.prototype.m1 = function () {
console.log(this); // C1 {k1: 'v1'}
};
const i1 = new C1();
i1.m1();
|class|
class C1 {
constructor() {
this.k1 = 'v1';
}
m1() {
console.log(this); // C1 {k1: 'v1'}
}
}
const i1 = new C1();
i1.m1();
3.6. in a class field method
※ I don't know how to call the function exactly. Sorry about that.
It refers to the instance.
class C1 {
k1 = 1;
m1 = function () {
console.log(this); // C1 {k1: 1, m1: ƒ}
};
}
const i1 = new C1();
i1.m1();
3.7. in a nested function
It refers to a 'window'.
|in a function in a regular function|
function outer() {
function inner() {
return this;
}
console.log([this, inner()]); // [window, window];
}
outer();
|in a function in a method|
const o1 = {
k1: 'v1',
m1() {
function f1() {
return this;
}
console.log([this, f1()]); // [o1, window]
},
};
o1.m1();
|in a function in a method of a constructor|
function C1() {
this.k1 = 'v1';
this.m1 = function () {
function f1() {
return this;
}
console.log([this, f1()]); // [i1, window]
};
}
const i1 = new C1();
i1.m1();
|in a function in a prototype method of a constructor|
function C1() {
this.k1 = 'v1';
}
C1.prototype.m1 = function () {
function f1() {
return this;
}
console.log([this, f1()]); // [i1, window]
};
const i1 = new C1();
i1.m1();
|in a function in an arrow function|
※ Let me cover how 'this' works in an arrow function later.
const o1 = {
k1: 'v1',
m1() {
console.log('outer', this);
return () => {
console.log('arrow', this);
return function () {
console.log('inner', this);
};
};
},
};
console.log(o1.m1()()());
// result
// outer {k1: 'v1', m1: ƒ}
// arrow {k1: 'v1', m1: ƒ}
// inner window
3.8. in a callback function
It refers to a 'window'.
|in a function in a regular function|
function f1(cb1) {
cb1();
}
function f2() {
console.log(this);
}
f1(f2); // window
|in a function in a method|
const o1 = {
k1: 'v1',
m1(cb1) {
cb1();
},
};
function f1() {
console.log(this);
}
o1.m1(f1); // window
|in a function in a method of a constructor|
function C1() {
this.k1 = 'v1';
this.m1 = function (cb1) {
cb1();
};
}
function f1() {
console.log(this);
}
const i1 = new C1();
i1.m1(f1); // window
|in a function in a prototype method of a constructor|
function C1() {
this.k1 = 'v1';
}
C1.prototype.m1 = function (cb1) {
cb1();
};
function f1() {
console.log(this);
}
const i1 = new C1();
i1.m1(f1); // window
4. In an Arrow Function
4.1. conclusion
It does not have its own 'this'.
4.2. in a method of an object
It refers to a 'window'.
const o1 = {
k1: 'v1',
m1: () => {
console.log(this); // window
},
};
o1.m1();
4.3. in a method of a constructor
※ I don't know how to call the function exactly. Sorry about that.
It refers to the instance.
|function|
function C1() {
this.k1 = 'v1';
this.m1 = () => {
console.log(this); // C1 {k1: 'v1', m1: ƒ}
};
}
const o1 = new C1();
o1.m1();
|class|
class C1 {
constructor() {
this.k1 = 'v1';
this.m1 = () => {
console.log(this); // C1 {k1: 'v1', m1: ƒ}
};
}
}
const o1 = new C1();
o1.m1();
4.4. in a prototype method of a constructor
※ I don't know how to call the function exactly. Sorry about that.
In case of function (not class), it refers to a 'window'.
|function|
function C1() {
this.k1 = 'v1';
}
C1.prototype.m1 = () => {
console.log(this); // window
};
const i1 = new C1();
i1.m1();
|class|
It is not possible to use an arrow function.
4.5. in a class field method
※ I don't know how to call the function exactly. Sorry about that.
It refers to the instance.
class C1 {
k1 = 1;
m1 = () => {
console.log(this); // C1 {k1: 1, m1: ƒ}
};
}
const i1 = new C1();
i1.m1();
4.6. in a nested function
What it refers to is different depending on situations.
|in a function in a regular function|
function outer() {
const inner = () => {
return this;
};
console.log([this, inner()]); // [window, window]
}
outer();
|in a function in a method|
const o1 = {
k1: 'v1',
m1() {
const f1 = () => this;
console.log([this, f1()]); // [o1, o1]
},
};
o1.m1();
|in a function in a method of a constructor|
function C1() {
this.k1 = 'v1';
this.m1 = function () {
const f1 = () => this;
console.log([this, f1()]); // [i1, i1]
};
}
const i1 = new C1();
i1.m1();
|in a function in a prototype method of a constructor|
function C1() {
this.k1 = 'v1';
}
C1.prototype.m1 = function () {
const f1 = () => this;
console.log([this, f1()]); // [i1, i1]
};
const i1 = new C1();
i1.m1();
4.7. in a callback function
It is determined not by where the callback is called, but by where the callback is defined.
|in a function in a regular function|
function f1(cb1) {
cb1();
}
const f2 = () => {
console.log(this);
};
f1(f2); // window
|in a function in a method|
const o1 = {
k1: 'v1',
m1(cb1) {
cb1();
},
};
const f1 = () => {
console.log(this);
};
o1.m1(f1); // window
|in a function in a method of a constructor|
function C1() {
this.k1 = 'v1';
this.m1 = function (cb1) {
cb1();
};
}
const f1 = () => {
console.log(this);
};
const i1 = new C1();
i1.m1(f1); // window
|in a function in a prototype method of a constructor|
function C1() {
this.k1 = 'v1';
}
C1.prototype.m1 = function (cb1) {
cb1();
};
const f1 = () => {
console.log(this);
};
const i1 = new C1();
i1.m1(f1); // window