Use and implementation of bind method in Javascript
During the interview, we often encounter the written test questions of handwritten bind, apply and call methods. Today, let's take a look at the bind method and implement the bind method to avoid being unable to answer during the interview.
First, learn what the bind method is and what functions it implements.
Look at the introduction on MDN
Function.prototype.bind()
The bind() method creates a new function. When bind() is called, this of the new function is specified as the first parameter of bind(), and the other parameters will be used as the parameters of the new function for calling.
Example:
var hello = function (a, b, c, d) { console.log(this.temp); console.log(a, b, c, d) }; var demo = { name: 'demo' }; var h = hello.bind(demo, 1, 2); h(3, 4); // out 'demo' '1 2 3 4 '
It can be seen that the bind method changes the this point inside the original function and returns a new function. Therefore, there should be a parenthesis behind it, that is, the corresponding result will not be obtained until it is executed. The first parameter in the first bracket in bind is regarded as this of the function, and the other parameters, including the parameters passed in when the function is executed later, are used by the original function in turn (coritization).
After understanding the above core, we can construct our own bind function.
First, bind returns a function. The first step is to say:
Function.prototype.myBind = function (){ return function(){ } }
Secondly, bind needs to take the first parameter in the first bracket after bind as this of the original function
To get the function input parameters, we need to know a little about the following arguments. Here is an example:
var test = function (a, b, c, d) { console.log(arguments) console.log(a, b, c, d) }; test(1, 2, 3) // Arguments(3) [1, 2, 3, callee: ƒ, Symbol(Symbol.iterator): ƒ] // 1 2 3 undefined
In other words, arguments arranges the parameters passed into the array into an array like object. We can obtain the parameters without defining additional formal parameters, which is very convenient. Through arguments Length we can know the number of parameters passed in.
Next, use arguments to continue the transformation:
Function.prototype.myBind = function () { // Save the first parameter passed in by bind const params_first = arguments[0] // Pass bind into the 2nd, 3rd, 4th Save the parameters const arg = [] for (let i = 1; i < arguments.length; i++) { arg.push(arguments[i]) } const that = this console.log(params_first, arg) return function () { return that } } hello.myBind(demo, 1, 2)()
Step by step, it is recommended that readers print here to see what functions we have implemented.
ok, after understanding the above process, we continue to make modifications. After all, we only realize the function of saving the parameters passed in by bind. Next, we need to realize that this of the original function points to the first parameter passed in as bind.
In short, this points to whoever calls it. Therefore, to realize this function, you need to change the original function into the attribute of the incoming object.
Function.prototype.myBind = function () { // Save the first parameter passed in by bind const params_first = arguments[0] // Pass bind into the 2nd, 3rd, 4th Save the parameters const arg = [] for (let i = 1; i < arguments.length; i++) { arg.push(arguments[i]) } // this points to the first parameter. Bind the original function to an attribute of the parameter params_first.tempUniqueFunction = this return function () { for (let i = 0; i < arguments.length; i++) { arg.push(arguments[i]) } const newFunction = params_first.tempUniqueFunction(...arg) // Don't add properties to the parameters out of thin air, so we have to delete them when we run out of them, so we use newFunction to save the new function pointed to by this delete params_first.tempUniqueFunction return newFunction } } hello.myBind(demo, 1, 2)(3, 4) // Combine the following code to print and see the effect var hello = function (a, b, c, d) { console.log(this.name) console.log(arguments) }; console.log(demo) // demo // Arguments(4) [1, 2, 3, 4, callee: ƒ, Symbol(Symbol.iterator): ƒ] // {name: "demo"}
Other optimization is to add some parameter verification. I won't do it here. In addition, other students can also use apply and call to realize it. Generally speaking, the ideas are similar, mainly if they can use it. Tomorrow I'll write about the implementation of apply and cal methods. Those who are interested can have a look.