Show Menu
Cheatography

JavaScript this binding in-depth Cheat Sheet (DRAFT) by [deleted]

This is a draft cheat sheet. It is a work in progress and is not finished yet.

5 this keyword binging rules

Default binging
this
points to a global object. Keep in mind: in the strict mode global object is
undefined
Implicit binding
A "­context object­" reference gets bound to
this
Explicit binding
this
gets bound to an object of our choice by calling explicitly
Functi­on.p­ro­tot­ype.call()
or
Functi­on.p­ro­tot­ype.ap­ply()
. Unfort­una­tely,
this
biding is lost in
=
assign­ments.
Explicit "­har­d" binding
"­Har­d" is just an implem­ent­ation of the
bind()
patter­n/m­ethod that addresses problem of
this
context lost in assign­ments
new f()
binding
An object, newly constr­ucted by
new
call, is set as
this
reference in function
f
this
binding rules apply to how
this
keyword gets evaluated in functions. The rules above are sorted from the most generic to the most specia­lised. Explicit "­sof­t" binding does not prevent us from losing
this
context

Default binding rule example

window.engine = "broken"; //global string
function startEngine() {
  console.log(this.engine + " started !");
};
startEngine(); //"broken started !"

Implicit binding rule example

window.engine = "broken";
function startEngine() {
  console.log(this.engine + " started !");
};
var raceCar = {
  engine: "560hp",
  startEngine: startEngine
};
raceCar.startEngine(); //"560hp started !"

Implicit binding rule broken

function startEngine() {
  console.log(this.engine + " started !");
};
var raceCar = {
  engine: "560hp",
  startEngine: startEngine
};
var startRaceCarEngine = raceCar.startEngine; //implicit binding lost !
startRaceCarEngine(); //"undefined started !"
 

Explicit rule example

function startEngine() {
  console.log(this.engine + " started !");
}
var raceCar = {
  engine: "560hp"
};
startEngine.call(raceCar); // "560hp started !"
startEngine.apply(raceCar); // "560hp started !"

Explicit binding rule broken

function startEngine() {
  return function() {
    console.log(this.engine + " started !");
  }
}
var raceCar = {
  engine: "560hp"
};
startEngine.call(raceCar)(); //"undefined started !"

Explicit "­har­d" rule example

function startEngineFactory() {
  return (function() {
    console.log(this.engine + " started !");
  }).bind(raceCar); //"hard" binding !
}
var raceCar = {
  engine: "560hp"
};
var startEngine = startEngineFactory();
startEngine({ engine: "78hp" });//"560hp started !"
startEngine.call({ engine: "51hp" });//"560hp started !"
no matter what you pass to startE­ngine() function, it is always bound to raceCar object instance

"­New­" rule example

function startEngine(power) {
  this.engine = power; //a new object
}
var slowCar = new startEngine("33hp");
var fastCar = new startEngine("260hp");
console.log(slowCar); //{engine: "33hp"}
console.log(fastCar); //{engine: "260hp"}
this gets bound to a newly created object (passed as this to the function body)

All rules in one example

window.engine = "broken";
function startEngine(power) {
  var log = this.engine + " preparing... ";
  this.engine = power;
  console.log(log + this.engine + " started !");
}
var raceCar = {
  engine: "560hp",
  startEngine: startEngine
};
startEngine("15hp"); //default binding
raceCar.startEngine("700hp"); //implicit binding
startEngine.apply({ engine: "[to-be-set]" }, ["440hp"]); //explicit binding
var newCar = new startEngine("33hp"); //"new" binding

//logs as follows:
//"broken preparing... 15hp started !"
//"560hp preparing... 700hp started !"
//"[to-be-set] preparing... 440hp started !"
//"undefined preparing... 33hp started !"