8 ms·
You can get a lot of value out of `Function#bind()`, which has been around since ES5. That doesn't let you curry functions, but it does give you partial applic
by kevincennis 11y ago
You can get a lot of value out of `Function#bind()`, which has been around since ES5.
That doesn't let you curry functions, but it does give you partial application, which I think is actually more useful on a day-to-day basis. If you're not familiar, here's a very quick and admittedly somewhat contrived example:
function clamp( lo, hi, val ) {
return Math.max( lo, Math.min( hi, val ) );
}
var tenToTwenty = clamp.bind( null, 10, 20 );
tenToTwenty( 5 ); // 10
tenToTwenty( 15 ); // 15
tenToTwenty( 25 ); // 20
For what it's worth though, I agree that having Function#curry in the ES spec would be pretty cool.
- satori99 11y agoI recently became aware that functions returned from bind perform realtively poorly in modern browsers. I am not sure of exactly why, but a simple closure outperforms the functions returned from bind() significantly in all the browsers i have ever tested in. If performance matters native bind() can be a pain.
- kevincennis 11y agoIt's all relative, right? If I'm writing some super perf-sensitive code like manipulating an array of PCM data for Web Audio stuff or doing a complex canvas animation, then the savings of not using Function#bind are probably kind of important. For most everyday code, avoiding bind() kind of feels like premature optimization to me.
- satori99 11y agoYeah, definately a realtive issue. And also easy to fix after the fact, but as you say, it becomes important for inner-loop stuff. I spent a few hours removing it from a codebase of mine last week, to see substantial improvements on all browsers.
- hajile 11y agoYou shouldn't use bind() for two very good reasons. First, it's performance is abysmal. Second, if you .bind(foo) a function and .call(bar) on it later, it silently ignores the new 'this' argument.
- juliangregorian 11y agoHyperbole much? Those aren't "very good reasons" to avoid an entire, useful language feature! I would like to know how exactly you find it's performance to be "abysmal" as I have used it in very high volume streaming code with no problems. The second "problem" is perhaps surprising to a newbie but is not hard to debug.
- jondubois 11y agoI haven't witnessed 'abysmal' performance either. Based on some tests I just ran, calling a bound function is only about 25% slower than calling a non-bound one. That's pretty reasonable. Calling bind() on a function doesn't appear to take that much CPU time either. That said I don't see the applications for currying in JavaScript. It just makes code less readable. It looks like an anti-pattern to me.
- hajile 11y agoAre you sure about those numbers (can you show your code?) Every benchmark I've seen shows a much bigger difference. Here's a jsperf (courtesy of the WayBackMachine) that shows a difference of about 20x+ over normal function calls. https://web.archive.org/web/20141121220218/http://jsperf.com/function-calls-direct-vs-apply-vs-call-vs-bind/33 https://web.archive.org/web/20141121220218/http://jsperf.com...
- hajile 11y agoRead the source code for yourself http://v8.googlecode.com/svn/trunk/src/v8natives.js http://v8.googlecode.com/svn/trunk/src/v8natives.js Another interesting example is Babel. In a fat arrow function, they would rather replace every instance of 'this' with a generated variable than add a .bind() to the end strictly based on overall performance. The second problem is surprising for everyone. The only thing you will see is that just before you enter the function, the 'this' is correct and immediately after, the 'this' changes. I've only ever spoke with a handful of devs who know this behavior happens. The biggest issue here is that if I use a third-party library and an external interface ever calls .bind(), then the abstraction will absolutely fall apart in a variety of circumstances. Considering that a simple `var self = this;` works in 99% of cases, I see no reason to encourage programmers to use .bind() in their code.