- Occurs automatically and implicitly when a function is called as a method of an object.
this
points to the object to the left of the dot.- Most common and useful rule, ~80% of the cases.
let me = { name: "Mauro", sayName: sayName };
function sayName () {
console.log("Hello, my name is", this.name)
}
me.sayName(); // Hello, my name is Mauro
- The easiest to spot because it's explicitly written by a programmer.
- Done with
.call
,.apply
and.bind
let me = { name: "Mauro" };
function sayName () {
console.log("Hello, my name is", this.name)
}
sayName.call(me) // Hello, my name is Mauro
var sayMauro = sayName.bind(me);
sayMauro(); // Hello, my name is Mauro
- Can override implicit binding
let me = { name: "Mauro" };
function sayName () {
console.log("Hello, my name is", this.name)
}
let boundSayName = sayName.bind(me);
let you = { name: "Ann", sayName: boundSayName };
you.sayName(); // Hello, my name is Mauro
- Inside a function that was called with the
new
operator. this
points to the new object being created.
function sayName () {
console.log("Hello, my name is", this.name)
}
function Person (name) {
// this = Object.create(Person.prototype) <-- Happens under the hood
this.name = name;
// return this <-- Happens under the hood
}
Person.prototype.sayName = sayName;
var me = new Person("Mauro");
me.sayName(); // "Hello, my name is Mauro"
// This rule depends on the use of `new`.
// See what happens if we don't use it:
var me = Person("Mauro");
console.log(me); // undefined, because `Person` doesn't return anything explicitly
me.sayName(); // TypeError, because me is `undefined` it cannot possibly have a `sayName` method
// we also leaked data into the global scope:
console.log(name); // Mauro
This happens because when we called Person
we didn't use the new
operator. The new
binding rule doesn't apply, nor the implicity and explicit ones. Therefore, the default rule applies and this
points to the global
object.
- Happens on "naked" function calls or when none of the other rules apply.
- Not a useful rule, just a "catch all".
- Depends on the environment in which we are running our program (browser, Node, etc.)
- In the browser,
this
points to thewindow
object. - If the function is in "strict mode",
this
points toundefined
function logThis () {
console.log(this);
}
// Naked function call
logThis(); // global object
[1, 2, 3].forEach(logThis);
// You'd think that `this` would point to [1, 2, 3] but it doesn't
// It points to the global object because `forEach` calls `logThis` "nakedly" internally
// (see your implementation of _.each)