Tuesday 12 June 2012

Function.create

Some weeks ago I mentioned this page. From there you can see what is being proposed for ES.next, the JavaScript of the future.

Looking at all the interesting (and some not so interesting) additions being debated or already approved, I tried to think of things that I'd like added.

  • One of them would be a huge change, and in fact could be of quite little use, extending the prototype mechanism to provide "multiple prototype inheritance". Well, with all the versatility of JavaScript we can have a sort of Multiple Inheritance just by extending (augmenting) the initial prototype (the main parent) with the items in the prototype of the second class
    
    Employee.prototype = new Person();
    $.extend(Employee.prototype, BusinessAsset.prototype);
    
    but that has some drawbacks, as explained here mainly the instanceof operator won't work for the additional base. As I think JavaScript is much more given to duck typing that to this kind of type checks, I guess we can live without it, but anyway, I think it would be nice that the [[prototype]] and prototype properties pointed to an Array instead of an object (I think to remember that's how it works in Python where __bases__ is an array)
  • The other one came to my mind influenced by the importance that Object.create seems to have gained with JavaScript 5. Indeed, I intend to write something (if I really grasp it...) about the advantages of Object.create vs constructors (you know, the common discussion now about whether JavaScript's "new" Keyword should be Considered Harmful.
    My idea is: wouldn't it be useful to have a Function.create function, that would allow us to choose the [[prototype]] for our function (instead of being forced to have the Function.prototype one)?

    Something along these lines:
    var extraFunctionality = {
    bind: function(){...},
    memoize: function(){...}
    }
    var myFunc = Function.create(extraFunctionality, function(){
    ...
    });
    

    So, you could be wondering, what does this buy us? Well, it's commonly accepted that modifying the prototype of base objects is bad practice, so adding functions to Function.prototype (prototype.js has got us used to it) should probably be avoided.
    A good solution would be grouping this functions in one object and then use that hypothetical Function.create function. An advantage of this is that we could add functions to only certain functions, and not all (for example, we could use this technique to add "memoize" only to some functions).
    This would also allow us to have functions which [[prototype]] would be null, losing this way the call and apply methods.
    If objects are allowed to have a null [[prototype]], why shouldn't functions be also allowed? (well, maybe because a function could be defined as an object which [[prototype]] points to Function.prototype).
    Well, the idea is confusing, bear in mind that we would then have prototype chains applied to functions... in a sense, thinking in terms of class based languages, in the end it would be like allowing inheritance between functions (methods).

    OK, all this is probably a nonsense, and all we should do is directly augment our functions themselves, something rather more conventional:

    $.extend(myFunction, {
    {
    bind: function(){...},
    memoize: function(){...}
    }
    

No comments:

Post a Comment