Making sense out of Context in JavaScript

Federico Knüssel
Dec 30, 2016 · 7 min read
function sayHi(name) {
console.log('Hello, my name is ' + name);
}

Context Bindings

Implicit Binding

var Person = function (name, age) {
return {
name: name,
age: age,
sayHi: function () {
console.log('Hi, my name is '+ this.name);
}
};
};
var homer = new Person('Homer Simpson', 30);
homer.sayHi(); // "Hi, my name is Homer Simpson"
var homer = {
name: 'Homer Simpson',
age: 26,
sayHi: function () {
console.log('Hi, my name is ' + this.name);
},
daughter: {
name: 'Lisa Simpson',
sayName: function () {
console.log('Hi, my name is ' + this.name);
}
}
};
homer.sayHi(); // Hi, my name is Homer Simpson
homer.daughter.sayHi(); // Hi, my name is Lisa Simpson

Explicit Binding

function getCountryDetails() {
console.log(this.country + '\'s capital city is '+ this.capital + ' and as of ' + arguments[0] + ' the country has a population of ' + this.population + ' according to ' + arguments[1]);
}
var oz = {
country: 'Australia',
capital: 'Canberra',
population: '23M'
};
var nz = {
country: 'New Zealand',
capital: 'Wellington',
population: '4M'
};
var today = '30/12/2016';
var source = 'Wikipedia';

i. Call

fun.call(thisArg[, arg1[, arg2[, ...]]])
getCountryDetails.call(nz, today, source);// "New Zealand's capital city is Wellington and as of 30/12/2016 the country has a population of 4M according to Wikipedia"

ii. Apply

fun.apply(thisArg, [argsArray])
getCountryDetails.apply(oz, [today, source]);// "Australia's capital city is Canberra and as of 30/12/2016 the country has a population of 23M according to Wikipedia"

iii. Bind

var getOzDetails = getCountryDetails.bind(oz, today, source);// nothing happens just yet...getOzDetails(); // we need to manually run the resulting function// "Australia's capital city is Canberra and as of 30/12/2016 the country has a population of 23M according to Wikipedia"
Function.prototype.bind = function (context) {
var fn = this;
var outerArgs = [].slice.call(arguments, 1);

return function () {
var innerArgs = [].slice.call(arguments, 0);
fn.apply(context, [].concat(outterArgs, innerArgs));
};
};
var missingSource = getCountryDetails.bind(oz, today);
var missingAllArgs = getCountryDetails.bind(oz);
missingSource(source);
missingAllArgs(today, source);

Let’s recap:

New Binding

var Dog = function (name, breed, color) {
// this = {} --> `this` equals to a brand new object
// being created by the `new` operator whenever the
// function gets instantiated.
this.name = name;
this.breed = breed;
this.color = color;
this.sayHi = function () {
console.log('My name is ' + this.name + ', woof woof!');
}
};
var puppy = new Animal('Axel', 'German Shepherd', 'Black');
puppy.sayHi();

Window Binding

function sayHi() {
console.log('Hi, my name is ' + this.name);
};
sayHi(); // undefined
window.name = 'Homer'; // might as well be `var name = 'Homer';`
sayHi(); // we now get "Hi, my name is Homer"
function sayAge() {
'use strict';
console.log(this.age);
};
sayAge(); // bummer! type error thrown ⚠️

ES6 Goodness: Arrow Functions

function () {
this.greeting = 'Good day mate';

// If we don’t bind this function, it'll echo out `undefined`
setTimeout(function () {
console.log(this.greeting);
}.bind(this));

// Binding here happens automagically using the parent scope
setTimeout(() => {
console.log(this.greeting);
});
}

Federico Knüssel

Written by

Front End Developer 👨‍💻 🇦🇺

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade