Improving Function.prototype.bind

John J Barton johnjbarton at johnjbarton.com
Sun Jan 8 12:29:08 PST 2012


On Sun, Jan 8, 2012 at 11:39 AM, Brendan Eich <brendan at mozilla.com> wrote:

> 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"?
>

Mine, Andrea's, Hewitt's Firebug at least.  I believe we have already
lamented our limited ability to analyze JS code patterns statistically.


> ...
>
> > 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've used "var self" and "var that" quite a lot. It's a hack, contributes
to right marching, stutters reading, but anyway the topic is bind() and how
it might be better. More important, I want my reply to highlight a
different meta-issue you raise: the role of libraries in testing ideas.


>
>
> > 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,


(Mark's case relies on believing that secure JS is a goal that trumps
usability; I hope too be converted to this belief soon).


> 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.
>


Standardizing library uses make sense, except here is an example of a
failure. The library version of bind() have exactly the problem we are
discussing here!

Why did we end up in this (hmm) bind? Somehow the standardization process
did not anticipate this issue even though it was known?

Firebug uses a library bind a lot, and we continually struggled with the
memoization problem; we did not try to solve it in part because we hated
Firebug's bind: it made debugging even more painful since it messes up the
call stack. Using the ES bind() ends up not being a win, since I now have
exactly the same problems.

jjb
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20120108/69685e0a/attachment.html>


More information about the es-discuss mailing list