Function.create

David Bruant david.bruant at labri.fr
Sat Sep 24 12:54:45 PDT 2011


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
>>



More information about the es-discuss mailing list