Functions in JavaScript are first-class citizens and can be passed around and used like ordinary variables. This flexibility allows functions to be used in various scenarios, such as invocation of object methods, creation of constructors, and prototypal inheritance. During the use of functions, call
, apply
, bind
are some of the more commonly used methods in JavaScript, which can change the context of function execution. You can also pass parameters.
In this article, we will introduce the three methods call
, apply
, bind
in detail, and manually simulate and implement them.
call
method
The call
method is used to call a function, and can set the value of this
inside the function. It allows you to point the this
object of a function to any object, and pass in any number of parameters.
Below is the basic syntax of the call
method:
function. call(thisArg, arg1, arg2, ...)
in:
function
: the function to be called.thisArg
: Sets the value of thethis
object in thefunction
function.arg1
,arg2
,...
: There can be multiple parameters passed to thefunction
function.
Here is a simple example:
const person = {<!-- --> name: 'Zhang San', sayHi() {<!-- --> console.log(`Hi, my name is ${<!-- -->this.name}.`); }, }; person.sayHi(); // output "Hi, my name is Zhang San." const otherPerson = {<!-- --> name: 'Zhang San', }; person.sayHi.call(otherPerson); // output "Hi, my name is Zhang San."
In the above example, we created a person
object, which has a sayHi
method for outputting self-introduction. We use the call
method to bind the sayHi
method of the person
object to the otherPerson
object, and output the otherPerson
The name of the object.
Next, we’ll manually mock the implementation of the call
method, implementing a function called myCall
.
Function.prototype.myCall = function(context, ...args) { context = context || window; context.fn = this; const result = context.fn(...args); delete context.fn; return result; };
In the above code, we added a new method myCall
to Function.prototype
. This method receives two parameters, the first parameter context
indicates the this
value to be bound, and the second parameter args
indicates the value to be passed to The parameter list for the function. If the first parameter context
is empty, it will be bound to the global object window
by default.
Next, we added a fn
attribute to the bound object context
, and bound the current function to this attribute, then called the function, and saved the result into the result
variable.
Finally, we remove the fn
attribute on the context
object and return the result. In this way, we have successfully manually mocked the implementation of the call
method.
apply
method
The syntax of the apply
function is: function.apply(thisArg, [argsArray])
, where thisArg
represents the context object when the function is executed, that is The object pointed to by the this
keyword in the function, argsArray
is an array, representing the parameter list passed when the function is executed.
Implementation steps
Declare a function to be used later with the apply
function.
function sum(a, b) {<!-- --> return a + b; }
Then we now need to add the apply
method to the function sum
, which accepts two parameters: the context object thisArg
and the argument array argsArray
.
Function.prototype.apply = function(thisArg, argsArray) {<!-- --> // Code };
In the apply
function, the first parameter thisArg
represents the context object to call the function. If no thisArg
is passed, it defaults to the global object window
.
Function.prototype.apply = function(thisArg, argsArray) { thisArg = thisArg || window; };
We need to point the this
keyword in the function to the context object thisArg
when the function is executed, thereby changing the context object of the function.
Function.prototype.apply = function(thisArg, argsArray) { thisArg = thisArg || window; let fn = Symbol('fn'); thisArg[fn] = this; let result = thisArg[fn](...argsArray); delete thisArg[fn]; return result; };
In the above code, we use a new Symbol
variable fn
to store the function object. Then we store the function object in the context object thisArg
and immediately execute the function, thus changing the function’s context object. Finally, we delete the function object stored in the context object and return the result of the function execution.
The following is the code implementation of the complete apply
function:
function sum(a, b) { return a + b; } Function.prototype.apply = function(thisArg, argsArray) { thisArg = thisArg || window; let fn = Symbol('fn'); thisArg[fn] = this; let result = thisArg[fn](...argsArray); delete thisArg[fn]; return result; }; console.log(sum.apply(null, [1, 2])); // Output: 3
bind
method
The bind
function is also a function to modify the this point of the function, which is different from the immediate execution of the call
and apply
functions, bind
The code> function returns a new function, which can be passed in parameters and executed in subsequent calls. Implementations of the bind
function can save the passed in this
value by using a closure in the returned new function, and return a new function.
The syntax of the bind
function is as follows:
function.bind(thisArg[, arg1[, arg2[, ...]]])
Among them, thisArg
is the value of this
that needs to be bound, and arg1
, arg2
etc. are the parameters of the new function. The bind
function returns a new function whose this
value is bound to the incoming thisArg
value, and additional parameters as arguments to the new function. When the returned new function is called, the original function will be called with the passed parameters and the previously bound this
value as parameters.
Here is a manually implemented bind
function:
Function.prototype.bind2 = function(thisArg) {<!-- --> var self = this; var args = Array.prototype.slice.call(arguments, 1); return function() {<!-- --> var bindArgs = Array.prototype.slice.call(arguments); return self.apply(thisArg, args.concat(bindArgs)); }; }
In the implementation, save the pointer of this
first, and then put the incoming parameters into the args
array. Then return a new function, this new function will save the this
value in the bind2
function and the parameters in the args
array. When the new function is called, it will combine the previously saved this
value and the parameters in the args
array with the newly passed parameters into one array, and call the original function The apply
method passes in this array as a parameter to achieve the purpose of modifying the value of this
and passing in parameters.
Summary
In this article, we introduced the functions and implementation principles of the three functions call
, apply
and bind
, and manually simulated and implemented these three functions . During the implementation process, we learned the this
pointer of the function, the apply
and call
methods of the function, and the currying of the function.
Mastering these knowledge points will help us better understand the function mechanism in JavaScript, and be able to write more flexible and efficient code.
Start the growth journey of Nuggets! This is the 7th day of my participation in the “Nuggets Daily New Project · February Update Challenge”, click to view the event details