Mutable `length` for functions?
Claude Pache
claude.pache at gmail.com
Tue Feb 26 02:13:47 PST 2013
An alternative to a writable 'length' property, is to make it configurable and nonwritable. It would prevent the issue of accidental assignments to the 'length' property that used be ignored in non-strict mode (they'll still be ignored), but it would allow to modify its value using Object.defineProperty.
—Claude
Le 25 févr. 2013 à 07:27, Nathan Wall <nathan.wall at live.com> a écrit :
> Would it be possible to make / what are the thoughts on making `length` mutable on functions?
>
> Writing to `length` could be a useful functionality for library code. For instance, implementing something like `bind` correctly requires the arity of the bound function to be the same as the original function minus the number of preloaded arguments.
>
> Simplified example:
>
> var slice = Function.prototype.call.bind(Array.prototype.slice);
> function bind(f, thisArg, ...args) {
> function bound() {
> return f.apply(thisArg, args.concat(slice(arguments)));
> }
> var L = f.length - args.length;
> bound.length = L > 0 ? L : 0;
> return bound;
> }
>
> Of course, `bind` is already on Function.prototype, so an ES6 library has no need to implement it. I'm only using bind as an example to establish precedent that writable `length` could be useful in implementing function wrappers. Consider as a more necessary example implementing an `uncurryThis` function.
>
> var uncurryThis = Function.prototype.bind.bind(Function.prototype.call);
> function foo(a, b, c) { /* ... */ }
> var uFoo = uncurryThis(foo);
> console.log(
> foo.length, // => 3
> uFoo.length // => 1
> );
>
> This is problematic because we lose information about the arity of the `uFoo` function which actually takes 4 arguments now: A `this` argument, `a`, `b`, and `c`. A simple solution would be to write an uncurryThis which corrects the arity:
>
> var bind = Function.prototype.call.bind(Function.prototype.bind),
> callMethod = Function.prototype.call;
> function uncurryThis(fn) {
> var F = bind(callMethod, fn);
> // Correct arity.
> F.length = fn.length + 1;
> return F;
> }
> function foo(a, b, c) { /* ... */ }
> var uFoo = uncurryThis(foo);
> console.log(
> foo.length, // => 3
> uFoo.length // => 4
> );
>
> Currently I have resorted to an `eval` based solution for creating wrapper functions which are defined with the correct number of arguments when a certain arity is desired. Obviously this is not ideal. Writable `length` would help a lot.
>
> Thoughts?
>
> Nathan
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss
More information about the es-discuss
mailing list