Improving Function.prototype.bind

Brendan Eich brendan at mozilla.com
Sun Jan 8 11:39:27 PST 2012


On Jan 8, 2012, at 10:47 AM, John J Barton wrote:

> That is why our code is now littered with:

BTW, which "our code"?


>    baz.boundOnLoad = baz.onLoad.bind(baz);  // bah, JS voodoo
> In my code I now have a function _bindListeners() called from initialize() where I list all of this goop.  The tedium is similar to reference counting.

The reference-counting tedium lies in the manual remove requirement. Reference counting has AddRef and Release (canonical COM names). It does not have a bind analogue. Indeed the bind requirement is more akin to requiring explicit handles or JNI-style roots for an exact GC. But we digress :-P.


> Yet another approach would mark methods as bound at declaration:
>   this.onLoad = function(event) {...}.bind(this);
> This approach (and other postfix solutions) are hard to follow since the ... pushes the salient info far from the name. (Plus this is a trap,  you have to be careful not to use it in literals).

Another way out is |this|-free code, which is trivial to arrange with single-window, window-level event handling. For multi-window or deeper-DOM receivers, you'll need var self = this in a closure that is memoized for removal. Others on this thread say they use the var that = this; style, so it's not as if everyone must use .bind.


> I don't know if Andrea's solution is good or not, but I want to put another vote for |"this| is a problem". 

Mark made the case for avoiding a capability leak channel in .bind, and that's what is specified by ES5. That ship sailed. In generating a fresh function each time, it mirrored the de-facto standard based on PrototypeJS, which uses closures (also fresh for each evaluation and opaque to reflection).

David Bruant keeps pointing out how ES5 library code can be used to polyfill a memoziing bind, and Mark observes surprising lack of leaks with a strong pre-ES6 emulation of WeakMap. These do not prove there is "no problem" to solve, on the contrary they allow a solution to be developed without serializing design through TC39 and pushing for premature standardization.

When I replied that lack of memoization is not a burning issue, I was not pooh-poohing anyone's pain, simply noting that this issue (AFAICR) has not come up till now on es-discuss.

In conjunction with the library solution that will be required in the field anyway (for all browsers until some future edition is widely implementend), this says to me that developers who need memoizing bind should build and popularize it, as Sam et al. did with PrototypeJS. Rather than push for incompatible or premature changes to the standard.

If such a de-facto-standard better-bind is built, we can easily de-jure standardize it. If it isn't, that says something too: that not everyone solves the problems for which you rely on bind in the same way.

/be


More information about the es-discuss mailing list