this
refers to an object and its value is determined by how a function is called.
Global
If this
is used outside a function, then this
refers to the gobal object, which is window
in browsers (whether in strict mode or not) or the global scope of a module in Node.
// browser
console.log(this === window); // true
// node
console.log(this === global); // true
Function
The value of this
depends on how a function is called.
Simple call
Inside a function not in strict mode, this
refers to the global object.
function whatIsThis() {
return this;
}
// browser
whatIsThis() === window // true
// node
whatIsThis() === global // true
Inside a function in strict mode, this
is undefined if its value isn't explicity set (more in this below)
function whatIsThis() {
return this;
}
// browser
whatIsThis() === undefined // true
// node
whatIsThis() === undefined // true
call and apply
You can explicit set the this
value inside a function by using the methods call
and apply
, which take an object as an argument.
// sample object
var moose = {
message: "I am this"
}
function whatIsThis() {
return this;
}
whatIsThis() // `window` or `global`
whatIsThis().call(moose); // `this` now refers to the moose object
whatIsThis().apply(moose): // `this` also now refers to the moose object
In this case, both call
and apply
work exactly the same. You can look up the differences in another part of this guide.
bind
bind
is like call
and apply
, but bind
creates a new function that's the same as the original function except that its this
value is explicitly set. In other words, when you use call
or apply
, you immediately invoke the function with this
already set. With bind
, you create a new function with this
set but the new function is not immediately invoked Furthermore you cannot use bind
more than once on a function to set and reset the this
value.
function whatIsThis() {
console.log(this.message);
}
let eagle = whatIsThis.bind({message: "I am an eagle"}) // set the `this` value`
eagle() // invokes the newly minted function, which will print the message "I am an eagle"
let falcon = whatIsThis.bind({message: "I am a falcon"}) // You cannot rebind the same function, which means no you are not a falcon. Instead this will print "I am an eagle"
arrow functions
Inside an arrow function, the value of this
is the same as the enclosing context, whether its the global context or the surrounding function context. If the arrow function exists in the global context, then this
refers to the global object.
// browser
let whatIsThis = () => { return this; }
whatIsThis() === window // true
Inside an arrow function, the value of this
cannot be changed by bind
, call
, or apply
.
// inside a browser:
var moose = {
message: "I am a moose"
}
let whatIsThis = () => {
return this;
}
console.log(whatIsThis.bind(moose)()) // not a moose but a window
console.log(whatIsThis.call(moose)) // not a moose but a window
console.log(whatIsThis.apply(moose)) // not a moose but a window
If an arrow function is defined inside other functions, the value of this
is determined by the enclosing function.
var moose = {
whatIsThis: function() {
// the value of `this` refers to the `moose` object
// we define an arrow function inside of another function, so the arrow function refers to the `this` value of the `whatIsThis` function, which points to the `moose` object
var x = (() => {
return this;
})
return x;
}
}
var whatIsThis = moose.whatIsThis();
console.log(whatIsThis()); // `moose`
// but if you reference the `moose.whatIsThis` method without invoking it, the `whatIsThis` method does not bind its `this` value based on the `moose` object context but rather on the global object. Therefore, the `this` value inside the arrow function refers to the global object as well.
var whatIsthis = moose.whatIsThis;
console.log(whatIsThis()()); // window
object method
Inside an object method, this
refers to the object on which the method is defined.
var moose = {
whatIsThis: function() {
return this;
}
}
console.log(moose.whatIsThis()); // moose
constructor
Inside a constructor function, the this
value refers to the new instance of the constructor function.
function Animal(species) {
this.species = species;
}
var moose = new Animal('I am a moose');
console.log(moose.species); // 'I am a moose'
If you decide to return an object inside a constructor function, the value of this
is then set to that return value.
function Animal(species) {
this.species = species;
return {
species: 'whoa'
}
}
var moose = new Animal('I am a moose');
console.log(moose.species); // 'whoa'
DOM event handler
Inside a callback function for an event handler, the this
value refers to the element on which the event originated.
document.querySelector('.anchor').addEventListener('click', function(event) {
event.preventDefault();
console.log(this); // .anchor
})
inline event handler
When this
is used in an inline event handler, the value of this
refers to the element on which the listener is placed
<button onclick="alert(this.tagName.toLowerCase());">
Show this
</button>
References
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this https://javascriptissexy.com/understand-javascripts-this-with-clarity-and-master-it/