Functions are the introduction of apply() and call().

Posted by ThunderLee on Sun, 12 May 2019 13:12:06 +0200

Application, call in function

When it comes to apply,call begins by talking about their origins with functions.

Javascript functions are both objects

It is no different from other javascript objects. And each function contains two non-inherited methods, apply() and call(), which can call functions indirectly.

For example:

function f() {
    console.log(1);
}
f.call(); //1
f.apply(); //1

, and both methods allow the display of this value after the call of the specified function.
With respect to this value, since this value is confirmed when entering the execution context stage, the value of this is puzzling. But we can use apply () and call () to display the required value when the function is called.

So what exactly are the apply and call methods used for?

Any function can be called by specifying this value as the method of the object pointed to by this.

That means that any function can be called by any object, which is the ultimate goal of the application and call methods.

Let's use an example to understand.

function Animal() {};
Animal.prototype = {
    constructor: Animal,
    other: function() {
        console.log('This is one.' + this.name);
    }
}
var animal = new Animal();
//Define an object
var dog = {
    name: 'Dog'
};

//What do my dog objects want to do with the other method of the Animal function, using call or apply
animal.other.call(dog);
animal.other.apply(dog);

On top of that, we call animal. other (think about what it is, yes, it's essentially a function) as a method call to a dog object. Next, let's use it more practically.

//Setting up a class array object
var arrLike = {
    0: 'I am apply',
    1: 'I am call',
    length: 2
}

//this of Arrar's slice function is explicitly pointed to arrLike, and 0 is passed into the slice function as a parameter.
var newArr = Array.prototype.slice.call(arrLike, 0);
//Equivalent to 
arrLike.slice(0);
console.log(newArr);

For apply() and cal(), all the first arguments passed into them will become the value of this, even if the incoming arguments are the original values, null,undefined. If undefined and null are the first arguments passed in, they will be replaced by global objects in ES3 and non-strict mode, while other original values will be replaced by corresponding wrapped objects.

In a popular way, Js doesn't care what the first parameter of apply/call is. The function will still be called, but whether the call will report an error is another matter.

var str = 'I am a function.';
//The string is passed in, but the String object cannot call the slice property to report an error.
Array.prototype.pop.call(str);

In order to memorize these two methods and when to use them, list some common usages.

Firstly, for now, the performance differences between the two methods are almost neglected, so how do they use them?

The apply() method is applicable to the case where the second parameter is ordered and the parameters are uncertain. For example, the arguments object of the function is suitable for passing as a parameter.

function A(a, b, c) {
    console.log(a, b, c);
}

var fn = (function(func, b, c) {
    var args = arguments;
    return () => {
        func.apply(null, args);
    }
}(A, 66, 99));

fn();

Let's say we add elements to an array.

var arr1 = [1, 2, 3];
var arr2 = [66, 99, 131];
Array.prototype.push.apply(arr1, arr2);
console.log(arr1);

The arr2 array is also passed as a parameter.

For disordered parameters that have no correlation with each other, call() is used.

Get the maximum and minimum values of an array

var arr = [0, 1, 2, 3, 4];

//Get the maximum number
var max1 = Math.max.apply(Math, arr),
    max2 = Math.max.call(Math, 0, 1, 2, 3, 4),

    //Get the minimum number
    min1 = Math.min.apply(Math, arr),
    min2 = Math.min.call(Math, 0, 1, 2, 3, 4);
console.log(max1, max2, min1, min2);

Array itself has no Math method, but we can use it with call or apply.

Judging the specific types of objects

//Specific types of validation objects
var arr = [];
var type = Object.prototype.toString.call(arr);
console.log(type);// [object Array]

When typeof is used, the results are all Objects, and it is impossible to determine which type it is. So you can use Object.prototype.toString.call() to get the specific type. Of course, the premise is that the toSting() method has not been rewritten

Converting class array objects to real arrays is usually done using Array.prototype.slice.call().

var arrLike = {
    length: 3,
    0: 'Value 1',
    1: 'Value 2',
    2: 'Value 3'
}
var newArr = [].__proto__.slice.call(arrLike);
var type = Object.prototype.toString.call(newArr);
console.log(newArr, type); //['Value 1','Value 2','Value 3']'[Object Array]'

Of course, splice and concat can also turn class array objects into arrays.

Let's popularize class array objects here.
Access elements by index and have length attributes
That is to say, two conditions need to be satisfied: 1. defining attributes by ordinal number, 2. owning length attributes, and the number of elements is the attribute value.
When using ordinal numbers to define attributes, it is recommended that attributes be defined in order starting from 0. Otherwise, the array element will be empty


var arrLike = {
    length: 3,
    0: 'Value 1',
    1: 'Value 2',
    3: 'Value 3'
}
var newArr = [].__proto__.slice.call(arrLike);
var type = Object.prototype.toString.call(newArr);
console.log(newArr, type); //['Value 1','Value 2', empty] [object Array]

Topics: Javascript Attribute