Bs:

I have been working on the front end for two years, but I still don’t know what apply, call, bind is. Or completely do not know the application scenario, just know that a lot of big guy by this implementation of a lot of SAO operation.

A basic understanding

This is copied from novice tutorial: www.runoob.com/w3cnote/js-…

Call (), apply(), and bind() are all used to redefine this!

The first of the three arguments is the this object you need to replace, followed by the argument passing. So the first parameter is required, and then the parameters you need to deal with

Call: The first reference to this is followed by the argument you want to pass in

Apply: The first parameter is this and the second parameter is an array

Bind: The first one is this, followed by the argument you’re passing in, but returns a new function

Just look at here really no one understand, application scenarios are also confused. All of the tutorials are about inheritance and changing the this point. But few start from actual business.

Today I finally understood one of bind’s real business scenarios, and I recently actually understood the meaning and use of ** higher-order functions (passing in a function and returning a function) **.

Example: our query list data interface

1. Before modification

Here is a piece of code from my actual business

Const querList = async page => {data.loading = true // Load start try {const result = await config.$api.psy. FileManageList ({const result = await config.$api.psy.  data: { ... data.queryParams, pageNum: page, pageSize: 1,},}) data.loading = false const {size, current, total, Pagination = {currentPage: current, total: total, pageSize: size, } console.log(records) data.tableData = records.map(li => {// array reprocessing const type = li.type li.type = filetypes.filter (ft) => ft. Value === type)[0]. Label return li})} Catch (e) {data.loading = false // Loading ends}}Copy the code

Personally, I used promise and async/await. If YOU don’t understand, hurry to learn.

That’s pretty much what I used to think, but now I’ve learned a little bit about higher-order functions

There is one thing we should pay attention to in business:

Loading means page loading, such as v-loading of element-UI, or global masking, which is essential. However, the loading parameter will be used many times, and each time it needs to be defined as true at the beginning and false at the end.

And in many of our actual scenarios, there may be more than one parameter, but it is the most basic, such as data initialization and so on.

As we get used to parameter action pages, controls, etc., parameters start to overflow. We found that the parameters started everywhere, but we had to define the state or we would get an error.

We can split code using the concept of higher-order functions or decorators

3. After modification

Basic modifier function

async function baseHandler(callback) {
      data.loading = true
      try {
        await callback()
        data.loading = false
      } catch (e) {
        data.loading = false
      }
    } 
Copy the code

Business list function

async function list(page = store.pagination.currentPage) { try { const result = await proxy.$Api.customerApi.userList({ data: { ... paramsHandler(), pageNumber: page, pageSize: 20, }, }) const { totalElements, contents } = result store.pagination = { currentPage: page, total: totalElements, pageSize: 20. } data.tableData = contents.map(li => { li.status = store.userType.filter(i => i.value === li.status)[0].label return li  }) return Promise.resolve(result) } catch (e) { return Promise.reject(e) } }Copy the code

After the combination

Function queryList() {return baseHandler(list)} queryList(1)Copy the code

Such a function can be executed. We’ve done higher-order functions, the same syntax as decorators. But we can’t pass in parameter 1.

Second, to solve the problem that parameters cannot be passed in

Modify 1

Function queryList(opt) {return baseHandler(list(opt))} queryList(1)Copy the code

The base decorator function will report an error indicating that it is not a function. Because your list has already been executed, returning a promise object or value.

Async function baseHandler(callback) {data.loading = true try {await callback() // prompt is not a function data.loading = false} catch (e) { data.loading = false } }Copy the code

The inelegant solution could be this

Function queryList(opt) {return baseHandler(() => {return list(opt)})} queryList(1)Copy the code

That’s fine but we can make it even simpler

Enter the bind function

We can directly change to the following way

Function queryList(opt) {return baseHandler(list.bind(this, opt))} queryList(1)Copy the code

This is not very code saving. We’ve done that the list is not executed, but it’s also given its incoming arguments.

So my personal summary of how bind is used is that you can either modify the this pointer or give an argument to it without executing the function

It’s easy for us to understand

Thank you for reading