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.If performance matters native bind() can be a pain.
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.
I spent a few hours removing it from a codebase of mine last week, to see substantial improvements on all browsers.
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.
https://web.archive.org/web/20141121220218/http://jsperf.com...
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.
Please tell me why you throwing reams of source code in my face is relevant.
> 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.
Source? Or could it be, shock, that a library that exists for compatibility is targeting environments without a native .bind()?
> The second problem is surprising for everyone.
It's only surprising for people who have never tried, never read the spec, and don't understand bind(). The spec clearly states that a bound function cannot be overridden. It's really not that difficult. It would be nice if you could provide clear examples of your problems because you're starting to not make sense.
Personally, I'd say the described behaviour made sense. If I bound a function, I'd want its `this` to remain bound, regardless of how I called it. That'w what one uses `.bind()` for. It seems counter-intuitive, to me, that one might want to explicitly `.bind()` something and then use it as if it had never been bound. In that case I'd `.call()` the original function with the new content object, rather than `.call()` the bound one.
Because the bind function implementation shows why it is so slow. If you read the spec like you imply, then reading one function shouldn't be difficult. You can write your own 'bind' function that skips a bunch of uncommon corner cases and get a huge boost in performance. Deal with the possible edge cases and performance tanks.
> Source? Or could it be, shock, that a library that exists for compatibility is targeting environments without a native .bind()?
It's not a matter of supporting older browsers. Babel target's IE9+ by default and has optional polyfills and transformers you must add if you want to support JS versions before ES5.1.
There was a discussion on Reddit about this very topic a few months ago. The poster got served by the Babel guys and deleted all their posts. Their claim was basically that `(foo) => this.foo` should translate into `function (foo) { return this.foo; }.bind(this)` and that Babel got it wrong. The response from sebmck was "There's no point in using bind when you can just remap all references to this which is significantly faster." [source](https://www.reddit.com/r/webdev/comments/30wwgk/an_overview_...).
If you want to know more on the topic, I'd suggest making a github issue so one of their team members can clarify things for you.
> It's only surprising for people who have never tried, never read the spec, and don't understand bind(). The spec clearly states that a bound function cannot be overridden. It's really not that difficult. It would be nice if you could provide clear examples of your problems because you're starting to not make sense.
The spec is fairly obscure about thisArg vs [[BoundThis]] and a full understanding encompasses not only a half-dozen user and internal functions, but also requires the reading about environments. This gets even more opaque in the ES2015 spec. That said, 99.5% of JS programmers will never read the spec (the ES5.1 spec is ~300 pages of extremely technical reading while the ES6 spec is ~600 pages and even harder to understand).
Here's a made-up example
var obj1 = {foo: 3};
var obj2 = {foo: 4};
var add = function (n) { return n + this.foo; }.bind(obj1);
add.call(obj2, 3); //=> 6
This may be easier to see in this little example, but if that definition is somewhere in a library and you use a .call() with a `this` that matters, your function will fail. When you step through with the debugger, you will see that your object that you're passing as the `this` is what you expect. When you step into the function, it will have suddenly changed to a different object.I assume the silent failure is because users may want to .apply() a function that is bound for the easy array destructuring, but I think that attempting to rebind the `this` too anything but null or undefined should yield an error of some kind.
Does it? I'm not going to pretend to know why that would be. Your explanation would be welcome.
I don't know if this sebmck fellow has benchmarked the code, but another commenter below found it to be a whopping 25% faster. Micro-optimizations, anyone?
> 99.5% of JS programmers will never read the spec
You don't have to read the spec, it's literally the first thing after the description paragraph on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
As others have mentioned, when I bind a function, I don't expect it to be able to be messed with.
Anyway, I'm done debating, but it should be quite obvious that there's no need to throw bind() away.
In FF39 on my machine, .bind() is between 5 and 20x slower. In Chrome 43, it's between 2 and 20x slower compared to call and apply and 200x slower compared to normal function calls (I ran several times and don't fully understand why Chrome optimizes the hell out of normal function calls).
I would encourage you to run it for yourself and see.
var cl = function () { console.log.apply(console, arguments); };