Demystify Array.prototype.slice.call()

And everything you want to know about JavaScript bind, call, apply method

Image for post
Image for post
Photo by Joanna Kosinska on Unsplash

Firstly, the “This” .

This is special in JavaScript. It is a property of an execution context (global, function or eval) that, in non–strict mode, is always a reference to an object and in strict mode can be any value.

  • Inside a function, the value of this depends on how the function is called. Since the following code is not in strict mode, and because the value of this is not set by the call, this will default to the global object, which is window in a browser. In strict mode, however, if the value of this is not set when entering an execution context, it remains as undefined .
  • Within a class constructor, this is a regular object. All non-static methods within the class are added to the prototype of this:
  • In arrow functions, this retains the value of the enclosing lexical context's this. In global code, it will be set to the global object.
  • When a function is called as a method of an object, its this is set to the object the method is called on.

Function.prototype.call()

The call() method calls a function with a given this value and arguments provided individually.

function Product(name, price) {
this.name = name;
this.price = price;
}
function Food(name, price) {
Product.call(this, name, price);
this.category = 'food';
}
function Toy(name, price) {
Product.call(this, name, price);
this.category = 'toy';
}
const cheese = new Food('feta', 5);
const fun = new Toy('robot', 40);
var sData = 'Wisen';function display() {
console.log('sData value is %s ', this.sData);
}
display.call(); // sData value is Wisen========================>
'use strict';
var sData = 'Wisen';function display() {
console.log('sData value is %s ', this.sData);
}
display.call(); // Cannot read the property of 'sData' of undefined

Function.prototype.apply()

apply() and call() are very identical except that call() accepts an argument list, while apply() accepts a single array-like arguments.

arguments[0] // first argument
arguments[1] // second argument
arguments[2] // third argument

And finally, Function.prototype.bind()

The bind() method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.

let boundFunc = func.bind(thisArg[, arg1[, arg2[, ...argN]]])
let arr = [];
arr.length; // 0
arr[0] = "a";
arr.length; // 1
arr.length = 0;
arr[0]; // undefined
this.x = 9;    
const module = {
x: 81,
getX: function() { return this.x; }
};
module.getX(); // 81const retrieveX = module.getX;
retrieveX(); // 9
const boundGetX = retrieveX.bind(module);
boundGetX(); // 81

The differences of bind, call and apply

You may notice that call/apply invokes the function immediately, while bind returns a function that, when later executed, will have the context set earlier. It is particularly useful in maintaining context in async callbacks and events.

const numbers = [5, 6, 2, 3, 7];
const max = Math.max.apply(null, numbers);
console.log(max);
// 7
function list() {
return Array.prototype.slice.call(arguments);
}
function addArguments(arg1, arg2) {
return arg1 + arg2
}
const list1 = list(1, 2, 3);
// [1, 2, 3]
const result1 = addArguments(1, 2);
// 3
// 37 is fixed
const leadingThirtysevenList = list.bind(null, 37);
// 37 is fixed
const addThirtySeven = addArguments.bind(null, 37);
const list2 = leadingThirtysevenList();
// [37]
const list3 = leadingThirtysevenList(1, 2, 3);
// [37, 1, 2, 3]
const result2 = addThirtySeven(5);
// 37 + 5 = 42
const result3 = addThirtySeven(5, 10);
// 37 + 5 = 42
// (the second argument is ignored

A final remark

As we can see, regardless of calling it later or earlier, call apply and bind are useful methods to enable re-using of built-in functions in different modules. We don’t need to specifically write a child class to inherit or extend from the parent class just to access one method. This is an important aspect of function borrowing, with one of the most popular native methods being Array.prototype.slice

function findB() {
var args = Array.prototype.slice.call(arguments)
return args.filter(a => a.includes('b'))
}

findO("bud", "bid", "bed", "bad")
=> [ 'bed' ]

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store