Call, Bind and Apply
tl;dr call, bind and apply are 3 really important methods that are available on all Javascript functions out of the box. Each method does the same kind of thing, but the invocations are different.
Prerequisites for this article
- Understanding of
thisin Javascript (good luck with that one) - Knowledge of objects and functions
- Ideally some Pokemon knowledge, but not essential
- A strong cup of coffee. Or tea. Or whatever gets you through articles about
this - A llama. For the vibes
Think of them like three siblings who all know how to cook but each one insists on doing it their own way. The food comes out the same, the process is just slightly different.
Call
call attaches this into a function, and then executes it immediately:
var pokemon1 = {
name: "Gary",
species: "Charizard",
type1: "Fire",
type2: "Flying",
health: 1000,
atk: 94,
};
var pokemon2 = {
name: "Barry",
species: "Blastoise",
type1: "Water",
type2: "",
health: 1000,
atk: 91,
};
function getFullName(connectingWord) {
var fullName = this.name + connectingWord + this.species;
return fullName;
}
getFullName.call(pokemon1, " is a "); // Gary is a Charizard getFullName.call(pokemon2, ' the ') // Barry the Blastoise
Apply
apply does the same thing as call, except it takes in an array of arguments. Thats literally the only difference. I know, you’d think it would be more dramatic:
var pokemon1 = {
name: 'Gary',
species: 'Charizard',
type1: 'Fire',
type2: 'Flying',
health: 1000,
atk: 94
};
var pokemon2 = {
name: 'Barry',
species: 'Blastoise',
type1: 'Water',
type2: '',
health: 1000,
atk: 91
};
function getAttacks(attack1, attack2) {
console.log(this.name + " has the following attacks: ")
console.log(attack1)
console.log(attack2)
}
getAttacks.apply(pokemon1, ['Fire Spin', 'Blast Burn']) getAttacks.apply(pokemon2, ['Water Gun', 'Hydro Cannon'])
Quick way to remember the difference: Call takes Comma separated arguments. Apply takes an Array. Done.
Bind
To understand bind a little better, let’s go deeper using the above example:
var pokemon1 = {
name: "Gary",
species: "Charizard",
type1: "Fire",
type2: "Flying",
health: 1000,
atk: 94,
attack: function () {
return (
Math.floor(Math.random() * (this.atk + 10 - this.atk + 1)) + this.atk
);
},
getFullName: function () {
var fullName = this.name + " the " + this.species;
return fullName;
},
};
var pokemon2 = {
name: "Barry",
species: "Blastoise",
type1: "Water",
type2: "",
health: 1000,
atk: 91,
attack: function () {
return (
Math.floor(Math.random() * (this.atk + 10 - this.atk + 1)) + this.atk
);
},
getFullName: function () {
var fullName = this.name + " the " + this.species;
return fullName;
},
};
function startBattle(pokemon1, pokemon2) {
console.log(pokemon1.getFullName() + " vs " + pokemon2.getFullName());
}
startBattle(pokemon1, pokemon2); // "Gary the Charizard vs Barry the Blastoise"
In the above example we can see there are some repeated methods as part of each object. It would be a lot clearer if we could define a function we can reuse on each Pokemon:
var pokemon1 = {
name: "Gary",
species: "Charizard",
type1: "Fire",
type2: "Flying",
health: 1000,
atk: 94,
attack: function () {
return (
Math.floor(Math.random() * (this.atk + 10 - this.atk + 1)) + this.atk
);
},
};
var pokemon2 = {
name: "Barry",
species: "Blastoise",
type1: "Water",
type2: "",
health: 1000,
atk: 91,
attack: function () {
return (
Math.floor(Math.random() * (this.atk + 10 - this.atk + 1)) + this.atk
);
},
};
function getFullName() {
var fullName = this.name + " the " + this.species;
return fullName;
}
function startBattle(pokemon1, pokemon2) {
console.log(
getFullName.bind(pokemon1)() + " vs " + getFullName.bind(pokemon2)()
); // "Gary the Charizard vs Barry the Blastoise"
}
startBattle(pokemon1, pokemon2);
Here you can see we’ve refactored the function to be standalone, and we are now invoking it using bind. This causes a copy of the pokemon object to be made. Unlike call and apply, bind doesnt execute the function straight away. It returns a new function with this baked in, ready to go whenever you call it. Like meal prepping but for functions.
Taking this example a step further, let’s see if we can refactor the attack function a little to demonstrate some other features of the bind function:
var pokemon1 = {
name: 'Gary',
species: 'Charizard',
type1: 'Fire',
type2: 'Flying',
health: 1000,
atk: 94
};
var pokemon2 = {
name: 'Barry',
species: 'Blastoise',
type1: 'Water',
type2: '',
health: 1000,
atk: 91
};
function getFullName() {
var fullName = this.name + ' the ' + this.species;
return fullName;
}
function attack(opponent) {
const name1 = getFullName.bind(this)()
const name2 = getFullName.bind(opponent)()
const hit = Math.floor(Math.random() * ((this.atk + 10) - this.atk + 1)) + this.atk // Calulates attack damage using this
opponent.health -= hit // Removes points from opponent
console.log(name1 + " hits for " + hit + " points")
console.log(name2 + "'s' health is " + opponent.health)
}
function startBattle(pokemon1, pokemon2) {
console.log(getFullName.bind(pokemon1)() + ' vs ' + getFullName.bind(pokemon2)())
}
startBattle(pokemon1, pokemon2)
const pokemonOneAttack = attack.bind(pokemon1)
const pokemonTwoAttack = attack.bind(pokemon2)
pokemonOneAttack(pokemon2)
pokemonTwoAttack(pokemon1)
pokemonOneAttack(pokemon2)
pokemonTwoAttack(pokemon1)
console.log(pokemon1) console.log(pokemon2)
Using bind we’ve now managed to create a standalone attack function that will calculate the hit damage of the current pokemon, and also take that amount off of the opponent. We can now reuse the pokemonOneAttack and pokemonTwoAttack functions whenever applicable.

The Quick Cheat Sheet
| Method | Executes immediately? | Arguments |
|---|---|---|
| call | Yes | Comma separated |
| apply | Yes | Array |
| bind | No (returns new function) | Comma separated |