Proposal: Function.prototype.bindContext

Andrea Giammarchi andrea.giammarchi at gmail.com
Thu Sep 17 19:56:55 UTC 2020


I'm not sure I'm following, but I'm not here to find solutions, I already
have solutions, I'm here to propose a new `Function.prototype.bindContext`
method that doesn't require any user-land discussion/prototype pollution.

Thanks.

On Thu, Sep 17, 2020 at 9:25 PM Adam Eisenreich <akxe at seznam.cz> wrote:

> This should able to be done via two nested WakMap,
>
> First level would be the function and the second the context or vice
> versa. This should be able to give you the same bound function while both
> are avaible, but should clear itself once the reference to function/context
> is lost.
>
> ---------- Původní e-mail ----------
> Od: Andrea Giammarchi <andrea.giammarchi at gmail.com>
> Komu: es-discuss at mozilla.org <es-discuss at mozilla.org>
> Datum: 17. 9. 2020 21:03:45
> Předmět: Proposal: Function.prototype.bindContext
>
> I've found myself (once again) polluting the `Function.prototype` with a
> lazy method that, once invoked, grants that the returned bound function is
> always the same, per context.
>
> # Use Case
>
> It's still a common footgun to add events either via `context.method` or
> via `context.method.bind(context)`, where the former footgan would invoke
> `method` with a global context/undefined instead of the expected context,
> while the latter would make it impossible to ever remove that listener
> later on.
>
> It's also common to use methods for timers sensitive things, and it's
> indeed not by accident that `console` got "self bound", or provided as
> namespace, when it used to throw if `setTimeout(console.log, 100, value)`
> was used, for example.
>
> # Proposal
>
> Provide a lazy `bindContext` method that grants that if a method/function
> bound the same context before, it always returns the same reference.
>
> # Implementation / Polyfill (lazy version)
>
> ```js
> Function.prototype.bindContext = function (context) {
>   const _ = new WeakMap;
>   this.bindContext = bindContext;
>   return bindContext.call(this, context);
>   function bindContext(context) {
>     if (!_.has(context))
>       _.set(context, this.bind(context));
>     return _.get(context);
>   }
> };
> ```
>
> # Implementation details
>
> As the method suggest, and differently from `bind`, `bindContext` accepts
> only one argument, and it should throw with any context that is primitive
> (boolean, number, string, undefined, null), like any WeakMap key would
> throw as well.
>
> # Why not user-land / libraries / helpers
>
> Because standardizing a well-known/needed utility to not footgun common
> patterns would make the debate regarding global prototypes pollution
> irrelevant, as it's the standard that helps us out.
>
> In a few words, this might erase tons of common mistakes, but it also
> could be simplified within some helper/library, as long as not all of them
> need to include the proposed polyfill through a package or another.
>
> Thanks for consideration 👋
>
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20200917/cf161d21/attachment-0001.html>


More information about the es-discuss mailing list