I hope that through this article, I can clearly improve my understanding of apply, call, and bind, and list some of their wonderful uses to deepen my memory.
apply、call
In javascript, call and apply exist to change the context (context) of a function when it runs. In other words, it is to change the direction of this inside the function body.
A major feature of JavaScript is that functions have the concepts of "definition context" and "runtime context" and "context can be changed".
Let me list a code example for you first:
function fruits() {} = { color: "red", say: function() { ("My color is " + ); } } var apple = new fruits; (); //My color is red
But if we have an object banana= {color : "yellow"} , and we don't want to redefine the say method for it, then we can use the say method of apple by call or apply:
banana = { color: "yellow" } (banana); //My color is yellow (banana); //My color is yellow
Therefore, it can be seen that call and apply appear to dynamically change this. When an object does not have a certain method (banana does not say method in this chestnut), but others are (apple has a say method in this chestnut), we can use call or apply to operate it with other object methods.
The difference between apply and call
For both apply and call, the functions are exactly the same, but the methods of accepting parameters are different. For example, there is a function defined as follows:
var func = function(arg1, arg2) { };
You can call it in the following way:
(this, arg1, arg2); (this, [arg1, arg2])
where this is the context you want to specify, it can be any JavaScript object (everything in JavaScript is an object), call needs to pass parameters in order, while apply means putting parameters in an array.
In JavaScript, the number of parameters of a function is not fixed, so if you want to use the applicable conditions, use call when your parameters are clearly known.
When you are not sure, use apply, and then push the parameter into the array and pass it in. When the number of parameters is uncertain, all parameters can also be traversed through the arguments array inside the function.
In order to consolidate and deepen memory, the following are some common uses:
1. Adding between arrays
var array1 = [12 , "foo" , {name "Joe"} , -2458]; var array2 = ["Doe" , 555 , 100]; (array1, array2); /* array1 value is [12 , "foo" , {name "Joe"} , -2458 , "Doe" , 555 , 100] */
2. Get the maximum and minimum values in the array
var numbers = [5, 458 , 120 , -215 ]; var maxInNumbers = (Math, numbers), //458 maxInNumbers = (Math,5, 458 , 120 , -215); //458
number itself does not have a max method, but Math has it, so we can use its method with call or apply.
3. Verify whether it is an array (provided that the toString() method has not been rewritten)
functionisArray(obj){ return (obj) === '[object Array]' ; }
4. Use array method for class (pseudo) arrays
var domNodes = (("*"));
There is an object structure called pseudo-array in Javascript. What is more special is the arguments object, and there are also those who call getElementsByTagName, which return NodeList objects, all of which belong to pseudo-arrays. The push, pop and other methods under Array cannot be used.
But we can convert it into a real array with the length attribute, so that domNodes can apply all the methods under Array.
Deeply understand and use apply and call
Let’s go to [borrow an interview question] to understand apply and call more deeply.
Define a log method so that it can proxy the method. The common solution is:
function log(msg) { (msg); } log(1); //1 log(1,2); //1
The above method can solve the most basic needs, but when the number of parameters passed is uncertain, the above method will fail. At this time, you can consider using apply or call. Note that the number of parameters passed here is uncertain, so it is best to use apply. The method is as follows:
function log(){ (console, arguments); }; log(1); //1 log(1,2); //1 2
The next requirement is to add a "(app)" dropout to each log message, such as:
log("hello world"); //(app)hello world
How to do it more elegantly? At this time, you need to think that the arguments parameter is a pseudo-array, which is converted into a standard array, and then use the array method unshift, like this:
function log(){ var args = (arguments); ('(app)'); (console, args); };
bind
After talking about apply and call, let’s talk about bind. The bind() method is very similar to apply and call, and can also change the pointing of this in the function body.
MDN's explanation is that the bind() method will create a new function, called a binding function. When this binding function is called, the binding function will use the first parameter of the bind() method when it is created as this, and the second parameter of the bind() method and the subsequent parameters plus the parameters of the binding function runtime itself as the parameters of the original function in order.
Let’s take a look at how to use it. In common monomer modes, we usually use _this , that , self , etc. to save this so that we can continue to reference it after changing the context. Like this:
var foo = { bar : 1, eventBind: function(){ var _this = this; $('.someClass').on('click',function(event) { /* Act on the event */ (_this.bar); //1 }); } }
Due to the Javascript-specific mechanism, the context environment has changed in eventBind:function(){ } to $('.someClass').on('click',function(event) { }). The above methods of using variables to save this are useful and there is no problem. Of course, using bind() can solve this problem more elegantly:
var foo = { bar : 1, eventBind: function(){ $('.someClass').on('click',function(event) { /* Act on the event */ (); //1 }.bind(this)); } }
In the above code, bind() creates a function. When this click event is bound to be called, its this keyword will be set to the value passed in (here refers to the parameters passed in when bind() is called). Therefore, here we pass in the desired context this (actually foo ) into the bind() function. Then, when the callback function is executed, this points to the foo object. Another simple chestnut:
var bar = function(){ (); } var foo = { x:3 } bar(); // undefined var func = (foo); func(); // 3
Here we create a new function func. When a binding function is created using bind() and it is executed, its this will be set to foo instead of the global scope like when we call bar().
There is an interesting question. If bind() is twice in a row, or bind() is three times in a row, then what is the output value? Like this:
var bar = function(){ (); } var foo = { x:3 } var sed = { x:4 } var func = (foo).bind(sed); func(); //? var fiv = { x:5 } var func = (foo).bind(sed).bind(fiv); func(); //?
The answer is that 3 will still be output both times instead of the expected 4 and 5. The reason is that in Javascript, multiple times bind() is invalid. For a deeper reason, the implementation of bind() is equivalent to using a function to wrap a call / apply internally. The second bind() is equivalent to wrapping the first bind() again, so the bind after the second time cannot take effect.
apply, call, bind comparison
So what are the differences and differences between apply, call, and bind? When to use apply, call, and when to use bind. A simple chestnut:
var obj = { x: 81, }; var foo = { getX: function() { return ; } } ((obj)()); //81 ((obj)); //81 ((obj)); //81
All three outputs are 81, but pay attention to the one using the bind() method, which has more brackets afterwards.
That is, the difference is that when you want to change the context, not execute immediately, but callbacks, use the bind() method. apply/call executes the function immediately.
Let's summarize again:
apply, call, and bind are all used to change the pointing of this object of the function;
The first parameters of apply , call , and bind are the objects this wants to point to, that is, the context you want to specify;
apply , call , bind can all use subsequent parameters to pass parameters;
bind returns the corresponding function, which is easy to call later; apply and call are called immediately.
Okay, this article has introduced the tutorial on enabling the usage journey mode of apply, call, and bind in Javascript. I hope you like it.