call

The first argument to the call method is the value to bind to this, followed by a list of arguments. When the first parameter is null, undefined, the default point is window.

var arr = [1, 2, 3, 89, 46]; var max = Math.max.call(null, arr[0], arr[1], arr[2], arr[3], arr[4]); / / 89Copy the code

It can be understood as follows:

obj1.fn(); 
obj1.fn.call(obj1);

fn1();
fn1.call(null);

f1(f2);
f1.call(null,f2);
Copy the code

Look at an example:

<script> var message = "My name is" var obj = {message: 'My name is: ' } function getName(firstName, lastName) { console.log(this.message + firstName + ' ' + lastName); Call (obj, 'Dot', 'Dolby'); call(obj, 'Dot', 'Dolby'); getName.call(undefined, 'Dot', 'Dolby'); getName('Dot', 'Dolby'); // The default first argument is undefined </script>Copy the code

apply

Apply takes two arguments, the first being the value to bind to this and the second being an array of arguments. When the first parameter is null, undefined, the default point is window.

Var arr =,2,3,89,46 [1]; var max = Math.max.apply(null,arr); / / 89Copy the code

It can be understood as follows:

obj1.fn();
obj1.fn.apply(obj1);

fn1();
fn1.apply(null);

f1(f2);
f1.apply(null,f2);
Copy the code

The only difference is that when a function needs to pass multiple variables, Apply accepts an array as input, while call accepts a series of individual variables.

Look at an example:

<script> var message = "My name is" var obj = {message: 'My name is: ' } function getName(firstName, lastName) { console.log(this.message + firstName + ' ' + lastName); } // use call to modify this to point to the first parameter getName.apply(obj, ['Dot', 'Dolby']); getName.apply(undefined, ['Dot', 'Dolby']); getName('Dot', 'Dolby'); // The default first argument is undefined </script>Copy the code

As you can see, obj is the object that serves as the function context, and this in getName refers to obj. The arguments firstName and lastName are placed in an array and passed to the getName function.

Call and apply can be used to borrow methods from other objects, using call() as an example:

var Person1 = function () { this.name = 'Dot'; } var Person2 = function () { this.getname = function () { console.log(this.name); } Person1.call(this); // call Person1 and change Person1's this to Person2's this} var person = new Person2(); person.getname(); // DotCopy the code

From the above we can see that the Person2 instantiated object Person gets the name of Person1 using the getName method. Because in Person2, person1.call (this) changes Person1’s this to Person2’s this, Person2 now has all the attributes and methods in Person1, Person. name=’Dot’, which is equivalent to Person2 inheriting the attributes and methods of Person1.

There’s no need to worry about when to use what. If your parameters are already in an array, use apply. If your parameters are scattered and unrelated, use Call. In the example above of finding the maximum value in a set of numbers, of course it makes sense to use apply.

bind

Much like call, the first argument is a reference to this, and the second argument is a list of received arguments. The difference is that the bind method returns a function and uses a list of arguments that BIND receives.

The return value of bind is the function

var obj = { name: 'Dot' } function printName() { console.log(this.name); } var dot = printName.bind(obj) console.log(dot); // function () {... } dot(); // DotCopy the code

The bind method does not execute immediately, but returns a function with the context this changed. The printName function does not change this, pointing to the global object Window.

Use of parameters

<script>
        function fn(a, b, c) {
            console.log(a, b, c);
        }
        var fn1 = fn.bind(null, 'Dot');

        fn('A', 'B', 'C');            // A B C
        fn1('A', 'B', 'C');           // Dot A B
        fn1('B', 'C');                // Dot B C
        console.log(fn.bind(null, 'Dot'));
        fn.call(null, 'Dot');      // Dot undefined undefined
    </script>
Copy the code

Interesting question, if YOU bind() twice in a row, or if you bind() three times in a row, what’s the value of the output? Like this:

var bar = function(){ console.log(this.x); } var foo = { x:3 } var sed = { x:4 } var func = bar.bind(foo).bind(sed); func(); / /? var fiv = { x:5 } var func = bar.bind(foo).bind(sed).bind(fiv); func(); / /?Copy the code

The answer is that both times it still prints 3, not 4 and 5 as expected. The reason is that multiple bind() is not valid in Javascript. Bind () encapsulates a call/apply function. A second bind() encapsulates a call/apply function, so any subsequent bind will not work.

Call passes the second and subsequent arguments as arguments to fn, whereas fn1’s arguments are actually further back from the arguments in bind.

Call, call, bind, apply, call, bind, call, call, bind, call, call, call, bind, call, call, call When to use apply, call, and when to use bind. A simple example:

var obj = { x: 81, }; var foo = { getX: function() { return this.x; } } console.log(foo.getX.bind(obj)()); //81 console.log(foo.getX.call(obj)); //81 console.log(foo.getX.apply(obj)); / / 81Copy the code

All three output 81, but notice the bind() method, which has parentheses behind it.

That is, the difference is that you use bind() when you want to change the context not immediately, but rather by calling back. Apply/Call executes the function immediately.

To sum up:

  • Apply, call, and bind are all used to redirect the function’s this object.
  • The first argument to apply, call, and bind is the object to which this refers.
  • Apply, call, and bind can all pass arguments using subsequent parameters.
  • Bind returns the corresponding function for later call; Apply and call are immediate calls.