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