Summary of the rules for the binding of this
in JavaScript
this
points to the object to the left of the dot.let me = { name: "Mauro", sayName: sayName };
function sayName () {
console.log("Hello, my name is", this.name)
}
me.sayName(); // Hello, my name is Mauro
.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
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
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.
this
points to the window
object.this
points to undefined
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)