Bind your functions with this one weird trick!
Sorry, I couldn’t resist.
I write this post with hesitation but excitement. I have enjoyed playing around with the new ECMAScript function bind syntax as proposed here. This is a very early proposal for addition in ES2016 (ES7, whatever) and could drastically change or even be scrapped. Therefore, I recognize that this post may become obsolete.
So what does the syntax actually look like?
That’s pretty much it. The proposal introduces a new
:: operator that
simplifies function binding. Essentially, it offers syntactic sugar for calling
apply methods on
Function.prototype. The equivalent
ES5 code is below:
We could call it a day at that, but I don’t want to devalue the power that this syntax affords us. Let’s explore the ramifications of this syntax further.
Granted, you might be using a framework for your Todo app or a library like
lodash for iteration, but I don’t doubt we’ve all used the native
methods on a different context at some point. It’s tedious and messy, but it gets
the job done.
Now, with function bind syntax, we can make this code more expressive and elegant:
The semantics remain the same, yet this reads more naturally and hides away the uglier syntax we’re accustomed to.
If you visit the proposal (link), you’ll see another example where we can import helper functions from a hypothetical iteration library to iterate over a collection. This creates a better separation of concerns between data structures and function calls on those structures through generalization.
like an event library. This becomes tricky when we desire a specific
context for our callback. Normally, we have to create a reference to
this in a
separate variable and refer to it in our callback, or we call
Function.prototype.bind on our callback, passing in
Again, this is a little messy and slightly ugly. But with function bind syntax, it becomes drastically simpler:
This is powerfully expressive. No function wrapping. No explicit
(we’re obviously still calling it via
::, but we hide away those details). We
are declaring our intent that these functions should be called in response to an
event, and we’re ensuring our
this context with minimal effort.
If I wasn’t already convinced by the function bind syntax, chaining is what really sold it for me. Recently, I have been using PhantomCSS and CasperJS for a CSS refactoring endeavor. Of course, I’m on the up-and-up and utilizing ES2015 via Babel to write my test suite. If you have not heard of PhantomCSS or CasperJS, I encourage you to check them out. PhantomCSS is a very promising project for automating visual regressions of your website. CasperJS is a wrapper over PhantomJS and SlimerJS, offering a higher-level API.
For this particular project, I represent web pages as classes according to a
minimal interface. They each have a
run method that takes in my
instance. From there, each class chains method calls on my
returning the result. It’s very “promisey.” (I also added a few custom methods
to my instance to wrap over some other methods to make them more “promisey.”)
To avoid duplication in some classes, I wanted to add some methods to the
casper instance that are specific to the concerns of that page. However, I
didn’t want to pollute the actual object instance. Function bind syntax to the
That is amazing! I can naturally express the chaining semantics while decorating my instance without altering it. Just as a reminder of what we would probably have to do without function bind syntax, here is some equivalent ES2015 code:
It gets the job done, but it doesn’t flow as nicely as our chaining example. Function bind syntax allows us to reduce how much code we write and effectively express this notion of flowing through each step.
If you’d like to try out function bind syntax, then I encourage you check it out with Babel. If you’ve not heard of Babel, it’s a transpiler that transforms ES2015/2016 code into ES5. You can learn more about Babel from its website (link) and learn how to use function bind syntax here.
Gripes, Caveats, Wishlist
I don’t think this syntax is without its faults. I’m not entirely sold on the
:: operator yet. Maybe it’s the baggage I carry from other languages
like Ruby, PHP, and CoffeeScript, each which use that operator for different
semantics. Another option might be the
-> operator, but it’s not my favorite
either (burnout from PHP and C, no doubt). The
:: operator might be the best
solution, and I don’t necessarily hate it.
I haven’t dived into the discussion over this spec, but to my knowledge there is
no affordance for partial application via this syntax. Recall that the
Function.prototype can also partially apply parameters to the bound
function by passing in additional arguments.