This
TL;DR
- Global Environment:
thisrefers to the global object. - Standalone Function:
thisrefers to the global object. - Object Method:
thisrefers to the object itself. - Constructor Function / Class:
thisrefers to the object instance. - Event Listener:
thisrefers to the DOM element. - Arrow Function: There is no
this. - call / apply / bind:
thisrefers to any specified value. thisis usually related to functions, so a quick rule of thumb is thatthisrefers 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
thisiswindowobject.In non-strict mode in Node.js, the default value of
thisisglobalobject.In strict mode, regardless of the execution environment, the default value of
thisisundefined.
'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,
thisrefers to the global objectwindow.function log() {
console.log(this);
}
log(); // windowObject Method
When a function is used as a method of an object,
thisrefers 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,
thisrefers 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,
thisrefers 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
thisvalue.However, arrow functions do not have their own
thisvalue, and they inherit thethisvalue 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 thethisof 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 thethisof the function tothisArg.applymethod is similar tocallmethod, the difference is thatapplymethod 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
thisbound 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
thisand points it to the global object. Therefore, we need to bind the value ofthisspecifically.// 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 outnullclass 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: