Function.create

David Bruant david.bruant at labri.fr
Sat Sep 24 13:16:33 PDT 2011


Le 24/09/2011 22:00, François REMY a écrit :
> What's the use case that justify it's good to change a prototype after
> the object' initialization?
Excellent question!
We've been over this question in the "Standardizing __proto__" thread
starting at [1] and the Firefox bug that triggered it [2].
Besides "subclassing" (which would be now solved with all the things I
mentionned before), the only example I have heard of and consider being
worth was [3] where there is GUI to create a JS environment. Here, I'm
not 100% sure __proto__ is necessary, but it sure is handy to implement
changing the prototype of an object dynamically.

David

[1] https://mail.mozilla.org/pipermail/es-discuss/2011-March/013131.html
[2] https://bugzilla.mozilla.org/show_bug.cgi?id=642500
[3] http://avocadojs.com/

>
>
> -----Message d'origine----- From: David Bruant
> Sent: Saturday, September 24, 2011 9:54 PM
> To: Xavier MONTILLET
> Cc: es-discuss at mozilla.org
> Subject: Re: Function.create
>
> Le 24/09/2011 19:30, Xavier MONTILLET a écrit :
>> I don't get the difference between the proto operator and some
>> setPrototype method that could be added (or the actual __proto__
>> property)...
> The proto operator works for initialization only on a newly created
> object while __proto__ allows to change the prototype anytime.
> ------
> var f = function(){}, a = [];
> var o = {};
>
> var f2 = o <| function(){}; // ok, new object created
> var a2 = o <| []; // ok, new object created
>
> var f3 = o <| f; // throw an error, because f is already an object with
> a prototype. Its prototype can't be changed dynamically
> var a3 = o <| a; // throws for the same reason
>
> f.__proto__ = o; // prototype changed
> a.__proto__ = o; // same
> ------
>
> David
>
>>
>> On Sat, Sep 24, 2011 at 6:03 PM, David Bruant <david.bruant at labri.fr>
>> wrote:
>>> Le 24/09/2011 15:33, Jake Verbaten a écrit :
>>>> There is no standardized way to create a new function with a prototype
>>>> which is not Function.prototype.
>>>>
>>>> I propose Function.create
>>>>
>>>>     /*
>>>>       Creates a new function whose prototype is proto.
>>>>       The function body is the same as the function fbody.
>>>>       The hash of propertydescriptors props is passed to
>>>> defineproperties just like
>>>>       Object.create does.
>>>>     */
>>>>     Function.create = (function() {
>>>>       var functionBody = function _getFunctionBody(f) {
>>>>         return f.toString().replace(/.+\{/, "").replace(/\}$/, "");
>>>>       };
>>>>       var letters = "abcdefghijklmnopqrstuvwxyz".split("");
>>>>
>>>>       return function _create(proto, fbody, props) {
>>>>         var parameters = letters.slice(0, fbody.length);
>>>>         parameters.push(functionBody(fbody));
>>>>         var f = Function.apply(this, parameters);
>>>>         f.__proto__ = proto;
>>>>         Object.defineProperties(f, props);
>>>>         return f;
>>>>       };
>>>>     })();
>>>>
>>>> This is the same as Object.create except the second parameter is a
>>>> function.
>>>>
>>>> It will create a new function whose function body is the same as the
>>>> function passed in.
>>>>
>>>> I don't believe this is possible to do in ES5 without __proto__
>>> It is not indeed.
>>> This topic has been discussed a couple of times here. There is one
>>> proposal that is more generic than your solution which is the proto
>>> operator [1].
>>>
>>> Basically, to create a function with a chosen prototype, you can do:
>>> -----
>>> var f = myProto <| function(a, b){return a+b;}
>>> Object.getPrototypeOf(f); // myProto
>>> f(1, 2); // 3
>>> -----
>>>
>>> I'm a big fan of the proto operator proposal, however, as raised
>>> previously this operator relies on the object being created to have an
>>> intialisation syntax. This prevents, for instance, Date objects to have
>>> a custom prototype with this method. I am not very familiar with it
>>> yet,
>>> but I think that if they ever came to life, ParallelArrays [2] would
>>> suffer from the same problem.
>>> By the way, could someone add this concern as a note ("open issue" or
>>> "limitation" or something like this) in the proto operator page,
>>> please?
>>>
>>> One even more generic way which would work even for objects that
>>> have no
>>> initialization syntax would to standardize one of [3] or [4]. Is
>>> there a
>>> wiki page mentionning these two functions somewhere? If not, may it be
>>> added and linked in some way to the proto operator?
>>>
>>> David
>>>
>>> [1] http://wiki.ecmascript.org/doku.php?id=harmony:proto_operator
>>> [2]
>>> https://github.com/RiverTrail/RiverTrail/blob/15ae7f6f77d9d2842d9d75458017efd9fe0fbee7/jslib/ParallelArray.js#L29
>>>
>>> [3]
>>> https://mail.mozilla.org/pipermail/es-discuss/2011-March/013141.html
>>> [4]
>>> https://mail.mozilla.org/pipermail/es-discuss/2011-March/013154.html
>>> _______________________________________________
>>> es-discuss mailing list
>>> es-discuss at mozilla.org
>>> https://mail.mozilla.org/listinfo/es-discuss
>>>
>
> _______________________________________________
> es-discuss mailing list
> es-discuss at mozilla.org
> https://mail.mozilla.org/listinfo/es-discuss



More information about the es-discuss mailing list