Function.create
David Bruant
david.bruant at labri.fr
Sat Sep 24 14:50:15 PDT 2011
Le 24/09/2011 22:25, François REMY a écrit :
> The last example you quoted would perfectly fit in the category "Use a
> Proxy to emulate the prototype chain, until the 'edited' object is
> serialized back to source code".
>
> If there's no strong use case that *need* to be able to set an object
> prototype to work, we should not ever consider that feature.
Rest assured that i agree 100% with that statement, I was just answering
your question.
> I really think Proxies provides all the functionnalities required to
> implement the special border cases where a non-conventionnal behavior
> is needed.
I do not think they do on their own, especially when it comes to object
identity (equality of objects after a call to Object.getPrototypeOf).
Proxies "suffer" from the same invariants than the regular objects which
is that Object.getPrototypeOf cannot lie (there is no trap for it).
However, with proxies + redefining Object.getPrototypeOf + adding a
custom Object.changePrototype(object, newProto) (which would /virtually/
change the prototype of a proxy (not a regular object!)), it could be done.
David
>
>
>
> -----Message d'origine----- From: David Bruant
> Sent: Saturday, September 24, 2011 10:16 PM
> To: François REMY
> Cc: Xavier MONTILLET ; es-discuss at mozilla.org
> Subject: Re: Function.create
>
> 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