Proposal: Function.prototype.bindContext
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)
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, mail.mozilla.org/listinfo/es-discuss "
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.
I think it's a good idea that would make things more efficient. +1 *#!/*JoePea
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 viacontext.method.bind(context)
, where the former footgan would invokemethod
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 ifsetTimeout(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)
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 👋