This
TL;DR
- Global Environment:
this
refers to the global object. - Standalone Function:
this
refers to the global object. - Object Method:
this
refers to the object itself. - Constructor Function / Class:
this
refers to the object instance. - Event Listener:
this
refers to the DOM element. - Arrow Function: There is no
this
. - call / apply / bind:
this
refers to any specified value. this
is usually related to functions, so a quick rule of thumb is thatthis
refers to the object that called the function.
What is this
The value of this
is determined at runtime, and can vary based on the execution environments, mode, and context.
In different modes or execution environments :
In non-strict mode in browser, the default value of
this
iswindow
object.In non-strict mode in Node.js, the default value of
this
isglobal
object.In strict mode, regardless of the execution environment, the default value of
this
isundefined
.
'use strict';
function log() {
console.log(this);
}
log(); // undefined
In non-strict mode in browser, different context:
- Global Environment
In the global environment, this
refers to the global object window
.
console.log(this); // window
Standalone Function
In a standalone function,
this
refers to the global objectwindow
.function log() {
console.log(this);
}
log(); // windowObject Method
When a function is used as a method of an object,
this
refers to the object itself.const foo = {
value: 123,
log() {
console.log(this);
},
};
foo.log(); // { foo: 123, log: [Function] }Constructor Function / Class
When a function is used as a constructor function or method of a class,
this
refers to the object instance.function Foo(value) {
this.value = value;
this.log = function () {
console.log(this);
};
}
const foo = new Foo(123);
foo.log(); // Foo { value: 123, log: [Function] }
class Boo {
constructor(value) {
this.value = value;
}
log = function () {
console.log(this);
};
}
const boo = new Boo(456);
boo.log(); // Boo { value: 456, log: [Function] }Event Listener
In an event listener function,
this
refers to the DOM element.const input = document.getElementById('input');
input.addEventListener('input', function () {
console.log(this); // <input id="input" />
});Arrow Function
In general, when a function is executed, it creates its own
this
value.However, arrow functions do not have their own
this
value, and they inherit thethis
value of their surrounding scope through the scope chain.const foo = () => this;
console.log(foo() === window); // true
A quick way to determine the value of this
is to look at how the function is called.
In other words, this
is the object that calls the function.
Set the value of this
Since this
is usually used inside functions, there are three methods to specify the value of this
.
call
function.call(thisArg, x, y, …):Calls the
function(x, y, ...)
and binds thethis
of the function tothisArg
.function log(a, b) {
console.log(this, a, b);
}
log.call(undefined, 'a', 'b'); // undefined 'a' 'b'
log.call(null, 'a', 'b'); // null 'a' 'b'
log.call('1', 'a', 'b'); // '1' 'a' 'b'
log.call(1, 'a', 'b'); // 1 'a' 'b'
log.call({}, 'a', 'b'); // {} 'a' 'b'
log.call([], 'a', 'b'); // [] 'a' 'b'apply
function.apply(thisArg, [x, y, …]):Calls the
function(x, y, ...)
and binds thethis
of the function tothisArg
.apply
method is similar tocall
method, the difference is thatapply
method takes an array as the second argument, which represents the arguments to pass to the function.function log(a, b) {
console.log(this, a, b);
}
log.apply(undefined, ['a', 'b']); // undefined 'a' 'b'
log.apply(null, ['a', 'b']); // null 'a' 'b'
log.apply('1', ['a', 'b']); // '1' 'a' 'b'
log.apply(1, ['a', 'b']); // 1 'a' 'b'
log.apply({}, ['a', 'b']); // {} 'a' 'b'
log.apply([], ['a', 'b']); // [] 'a' 'b'bind
function.bind(thisArg, x, y, …): returns a new function that, when called, will have its
this
bound tothisArg
.function log(a, b) {
console.log(this);
return a + b;
}
const myLog = log.bind('jordan', 1, 2);
log(); // window
myLog(); // 'jordan'
FAQ
Determine the result
var name = 'jordan1';
function callName() {
console.log(this.name);
}
const person = {
name: 'jordan2',
callName: callName,
watch: {
name: 'jordan3',
callName: callName,
},
};
person.callName();
person.watch.callName();
console.log(this.name);Answer:
person.callName(); // jordan2
person.watch.callName(); // jordan3
// Since name is declared using var, it is bound to the global object.
this.name; // jordan1Rewrite the following code to print out 'jordan'
const person = {
name: 'jordan',
print() {
setTimeout(function () {
console.log(this.name);
}, 1000);
},
};
person.print();Answer:
The function executed by setTimeout is not a method of an object, but just a regular function.
When the function is executed, it creates its own
this
and points it to the global object. Therefore, we need to bind the value ofthis
specifically.// 1. that
const person = {
name: 'jordan',
print() {
const that = this;
setTimeout(function () {
console.log(that.name);
}, 1000);
},
};
// 2. bind
const person = {
name: 'jordan',
print() {
setTimeout(
function () {
console.log(this.name);
}.bind(person),
1000,
);
},
};
// 3. arrow function
const person = {
name: 'jordan',
print() {
setTimeout(() => {
console.log(this.name);
}, 1000);
},
};How to let
jordan.log()
print outnull
class Person {
constructor(name) {
this.name = name;
}
log() {
console.log(this);
}
}
const jordan = new Person('jordan');Answer:
jordan.log.apply(null); // null
jordan.log.call(null); // null
Reference: