JavaScript function call, apply and bind method case study

JavaScript function call, apply and bind method case study

Summarize

1. Similarities

  1. Both can change the internal this pointer when the target function is executed.
  2. The first parameter of the method is used to specify the internal this value when the function is executed.
  3. Support passing any number of parameters to the target function
  4. If you do not pass a value to the first parameter of the method or pass undefined or null, then in JavaScript normal mode, this inside the target function points to the window object, and in strict mode, it points to undefined or null respectively.

2. Difference

  1. The apply() method accepts two parameters, while the call() and bind() methods accept multiple parameters.
  2. When the apply() method passes parameters to the target function, it only needs to pass the parameter array or arguments object as the second parameter of the method, while the call() and bind() methods need to list the parameters one by one after a parameter of the method.
  3. When the call() and apply() methods are called, the target function is executed immediately, but the bind() method will not. It will return a new function - a copy of the target function. The this inside the function points to the first parameter of the bind() method. Executing the new function afterwards is equivalent to executing the target function.
  4. Only the bind() method implements function currying, so it can pass parameters to the target function twice.

call() method

  1. Calling the call() method will immediately execute the target function and change the reference of this inside the function. This points to the first parameter of the method, and any parameters listed one by one will be passed in as parameters of the target function one by one.
  2. For the last point of the same point in the opening summary, the example is as follows:
/* Normal mode */

let obj = {
  sum(a, b) {
    console.log(this)
    return a + b
  }
}

// Execute the apply and bind methods of the sum function. The printed this is the same as below. obj.sum.call() // Print window
obj.sum.call(undefined, 1, 2) // Print window
obj.sum.call(null, 1, 2) // Print window
/* Strict mode */
'use strict'

// Execute the apply and bind methods of the sum function, and print this as below obj.sum.call() // Print undefined
obj.sum.call(undefined, 1, 2) // prints undefined
obj.sum.call(null, 1, 2) // prints null

Simulation Implementation

1. Key points

  1. The myCall() method is added to the Function prototype object. When the target function calls this method, this inside the myCall() method will point to the target function.
  2. Execute the target function as a method of the context object, so that this inside the target function will point to the context object. .
  3. Remove the target function from the context object
  4. Use the spread operator... to process the parameters passed into the target function

2. In the simulation implementation of call(), apply(), and bind() methods, when the first parameter is not passed or undefined or null is passed, unified processing is done here in JS normal mode and strict mode, that is, this inside the target function points to the window object.

3. The code is as follows

Function.prototype.myCall = function (context, ...args) {
  if (context === undefined || context === null) {
    context = window
  }
  // The following line is the core code context.fn = this
  const result = context.fn(...args)
  delete context.fn
  return result
}

let obj1 = {
  basicNum: 1,
  sum(a, b) {
    console.log(this)
    return this.basicNum + a + b
  }
}
let obj2 = {
  basicNum: 9
}
console.log(obj1.sum.call(obj2, 2, 3)) // 14
console.log(obj1.sum.myCall(obj2, 2, 3)) // 14

apply() method

Calling the apply() method will immediately execute the target function and change the reference of this inside the function. This points to the first parameter of the method. The second parameter is a parameter array or an arguments object. Each parameter represented by each array element or arguments object will be passed in one by one as the parameter of the target function.

Simulation Implementation

1. Key points

  1. The myApply() method is added to the Function prototype object. When the target function calls this method, this inside the myApply() method will point to the target function.
  2. Execute the target function as a method of the context object, so that this inside the target function will point to the context object.
  3. Remove the target function from the context object
  4. Use the spread operator... to process the parameters passed into the target function

2. The code is as follows

Function.prototype.myApply = function (context, args) {
  if (context === undefined || context === null) {
    context = window
  }
  // The following line is the core code context.fn = this
  const result = context.fn(...args)
  delete context.fn
  return result
}

console.log(obj1.sum.apply(obj2, [2, 3])) // 14
console.log(obj1.sum.myApply(obj2, [2, 3])) // 14

bind() method

  1. Calling the bind() method will return a new function - a copy of the target function. The this inside the function points to the first parameter of the method. Any parameters listed one by one will be passed in as parameters of the target function one by one. Executing the new function afterwards is equivalent to executing the target function.
  2. The bind() method implements function currying, so you can pass parameters to the target function twice. The first parameter is listed after the first parameter of the bind() method, and the second parameter is listed in the new function.

Simulation Implementation

1. Key points

  1. The myBind() method is added to the Function prototype object. When the target function calls this method, this inside the myBind() method will point to the target function.
  2. Execute the target function as a method of the context object, so that this inside the target function will point to the context object.
  3. Remove the target function from the context object
  4. Use the spread operator... to process the initial and subsequent parameters passed into the target function.

2. The code is as follows

Function.prototype.myBind = function (context, ...initArgs) {
  if (context === undefined || context === null) {
    context = window
  }
  // Cache this value const _this = this
  return function (...args) {
    // The following line is the core code context.fn = _this
    const result = context.fn(...initArgs, ...args)
    delete context.fn
    return result
  }
}

console.log(obj1.sum.bind(obj2, 2)(3)) // 14
console.log(obj1.sum.myBind(obj2, 2)(3)) // 14

Related knowledge points

  • About the reference of this in JavaScript

This is the end of this article about the detailed case analysis of JavaScript function call, apply and bind methods. For more relevant content about JavaScript function call, apply and bind methods, please search for previous articles on 123WORDPRESS.COM or continue to browse the following related articles. I hope you will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • Detailed explanation of this pointing in JS arrow function
  • JavaScript function syntax explained
  • Detailed explanation of the use of Vue.js render function
  • JavaScript Basics Series: Functions and Methods
  • JavaScript CollectGarbage Function Example
  • Detailed explanation of JavaScript function introduction

<<:  A tutorial for beginners to install and log in to mysql-8.0.19-winx64 (must-read for beginners)

>>:  How to use the realip module in Nginx basic learning

Recommend

Where is mysql data stored?

MySQL database storage location: 1. If MySQL uses...

How to write a picture as a background and a link (background picture plus link)

The picture is used as the background and the lin...

How to use JS WebSocket to implement simple chat

Table of contents Short Polling Long-Polling WebS...

Detailed explanation of Vue element plus multi-language switching

Table of contents Preface How to switch between m...

Issues with locking in MySQL

Lock classification: From the granularity of data...

Tutorial on installing MySQL on Alibaba Cloud Centos 7.5

It seems that the mysql-sever file for installing...

Two problems encountered when deploying rabbitmq with Docker

1. Background The following two problems are enco...

Flex layout allows subitems to maintain their own height

When using Flex layout, you will find that when a...

CSS3 animation – steps function explained

When I was looking at some CSS3 animation source ...

Analysis of MySql index usage strategy

MySql Index Index advantages 1. You can ensure th...

Clever use of webkit-box-reflect to achieve various dynamic effects (summary)

In an article a long time ago, I talked about the...

Vue example code using transition component animation effect

Transition document address defines a background ...

In-depth understanding of the use of r2dbc in MySQL

Introduction MySQL should be a very common databa...

Introduction to using the MySQL mysqladmin client

Table of contents 1. Check the status of the serv...

A simple example of MySQL joint table query

MySql uses joined table queries, which may be dif...