Top 3 useful methods in JavaScript function prototype— call, apply, bind
There’re three similar methods in Function.prototype, call, apply and bind, these three methods could change the dynamical `this` in function, I’ll not talk too much about `this`, but more about these methods’ ins and outs.
Chinese: [JavaScript] 函數原型最實用的 3 個方法 — call、apply、bind
So, in this article, I’ll do compare with a(apply) / b(bind) / c(call), and little bit concept of function `this`, in last, will take a practical use case about self, bind, arrow function.
Let’s start our trip.
Why we need apply / bind / call ?
JavaScript (so called ECMAScript) is a dynamic programming language, the “dynamic” sounds abstract, you might think “yeah … but I also learned other dynamic programming languages”, but the point is, the function `this` is dynamic.
Let’s see the common use case of apply / bind / call:
You’ll get the same output, these three can do the same thing as L8–9.
Please tell me what’s the magic behind these three methods!
Let’s classify to call, apply vs bind :
- call, apply return function result
- bind method return the function with binding `this`
We can figure out that bind method doesn’t wanna call the function.
The usage of Function.prototype.call()
The
call()
method calls a function with a giventhis
value and arguments provided individually. (src. MDN)
Honestly, I do not really understand it when I first saw this…
As my words, we can just shift the `arguments` to right, and tell the function `this` what we wanna use in the first parameter.
Except the first parameter, it’s 87% similar as original function call:
func(1, 2, 3) vs func.call(null, 1, 2, 3)
So, Function.prototype.apply() is just a shortcut
func.apply(thisArg, [argsArray])
The interface of apply()
only receive two parameters, you know the first one (yup, `this` again), and the second one is the arguments but it’s array.
func( 1 , 2 , 3 ) vs func( null , [ 1 , 2 , 3 ] )
A special point, there’s a preserve variable `arguments`, it’s array, so if you use `apply` method, you don’t need to do destructuring assign :
Just said, in the upper use case, we can easily solve that using `bind`.
How’s Function.prototype.bind()?
When you search on web, you’ll find out there’re thousands article wanna tell you how awesome you can do `currying` with `bind` method, why it’s a good practice, bla bla…
Let’s deep dive in bind, what bind want to do.
bind — different from the upper two, we don’t need pass the function’s parameter, and it’ll not return the result either, it’ll return “A function with the fixed this what you pass”, yes fixed, when you do, you cannot change the function `this` anymore.
In L6, we bind the function wtf_bind_window
first, so this function use the fixed this — window, you cannot change anymore even call, apply, or do bind again.
Do you really need bind()?
This is a classic case, you might have seen that when you make a callback function in class:
When you running the `laterHello`, the timer callback cannot get the correct this (which should point out to class instance), you can see it’s a very common case in Node’s class and React / Vue ’s class component.
There’re 3 ideas to solve this, `bind` is the one, but not the best one:
1 Self — something the JS developer love to use in class…
When you maintain the legacy project, you’ll see this most time.
Why I put it in the first one? Since it’s the low thinking cost solution, just use self, just follow the original pattern, no magic, no error, and easily review.
2 Binding — yup, so after reading this article, you have another choice
In this solution, there’s a big advantage of it, you don’t need to do any change in the inner callback function, but just tell what’s the correct `this` you want to apply.
In real world you don’t want to do much change but just reuse the function in callback, it might has much `this` you need to update to `self`.
But there’s another solution after ES6.
3 Arrow function — ikr, you don’t want self, but bind is hard to learn.
There’s a best thing in JavaScript that if you don’t want to learn a feature, you can just drop it out, there’s another different pattern to solve the same scenario. LMAO.
In most cases, arrow function has no difference from normal function, the only special is, the function `this` of arrow function always point out the context scope, and it’s fixed, even you do apply, bind and call, arrow function always got the this from context scope.
Conclusion
I finally finish this article, the best profit of writing articles is that I could understand more clear when introducing to others, hope you guys love it!
And next time you learn something like currying or function this, you can just refer from this article, hope it helps!