Jump to navigation

Call, Apply & Bind

Use .call() or .apply() when you want to invoke the function immediately, with modification of the context. Use .bind() when you want that function to later be called with a certain context, useful in events.

Call & Apply

You use call or apply when you want to pass a different this value to the function. In essence, this means that you want to execute a function as if it were a method of a particular object. The only difference between the two is that call expects parameters separated by commas, while apply expects parameters in an array.

function Product(name, price) {
  this.name = name;
  this.price = price;
}

function Food(name, price) {
  Product.call(this, name, price);
  this.category = 'food';
}

console.log(new Food('cheese', 5));
//Food {name: "cheese", price: 5, category: "food"}

Call

var bankInterest = {
  interestRate: 1,
  total: function(balance) {
    return (this.interestRate / 100) * balance;
  }
}

bankInterest.total(300)

Call allows you change the context of the function on the fly, eg in this case changing the interest rate

bankInterest.total.call(context, function arguments)

bankInterest.total.call({interestRate: 50}, 300)

Apply

Apply is exactly the same, but function arguments are passed as an array

bankInterest.total.apply({interestRate: 50}, [300])

Call or apply?

Use apply if you don't know the number of arguments you will be passing, or if they are already in an array or array-like object (like the arguments object to forward your own arguments. Use call otherwise, since there's no need to wrap the arguments in an array. Matthew Crumley

Bind

Bind attaches a brand new this to a given function. In bind’s case, the function is not executed instantly like Call or Apply.

// binding - but NOT immediatly calling - the interest rate
var something = bankInterest.total.bind({interestRate: 50});

// Later on...
console.log(something(300));

Bind allows us to inject a new context and call it whenever we like after. This is especailly useful as we can change the values of this to be whatever we like, eg changing interest rates for different customers

var paul = bankInterest.total.bind({interestRate: 50});
var john = bankInterest.total.bind({interestRate: 51});

Refs