Erik Arvidsson wrote:
Unfortunately there are use case (although limited) that cannot be solved without a mutable __proto__. Extending built *classes* is one such use case.

function HelloElement() {
  var el = document.createElement('div');
  el.__proto__ = HelloElement.prototype;
  el.text = 'Hello';
  return el;
}
HelloElement.prototype = {
  __proto__: HTMLDivElement.prototype,
  set text(text) { this.textContent = text; },
  say: function() {
    alert('Hello');
  }
};

document.body.appendChild(new HelloElement).say();
That design is used by some js libraries. Mutable __proto__ allow us to change prototype chain of created object and safe internal methods of that object. For example:

function f() {}
f.__proto__ = {
   __proto__ : Function.prototype
};

f(); //still have [[Call]] method
new f(); //still have [[Construct]] method

FuseJS use design like that for augment native objects. http://github.com/jdalton/fusejs The author use factories, which create native objects and mutate __proto__ instead of augmentation directly created object. Lets suppose the follows factories:

var Factory = (function () {
   function object() {
       return {__proto__ : object.prototype};
   }
object.prototype.augment = function() {
       //...
   };
function array() {
       var arr = Array.apply([], arguments);
       arr.__proto__ = array.prototype;
       return arr;
   }
array.prototype = {
       __proto__ : Array.prototype
   };
return {
       object : object,
       array : array
   };
})();

var obj = Factory.object();
/*Augment created object with new properties*/
obj.augment({
   property1 : true,
   property2 : true,
   propertyN : true
});

var arr = Factory.array();
/*Augment created array with new properties*/
arr.augment({
   property1 : true,
   property2 : true,
   propertyN : true
}); //Type Error

Cannot be shared properties by object.prototype and array.prototype, because they are not in same prototype chain. For generic methods you need copy reference in both object, which is not good. Of course that design is a little bit step forward instead of augmentation, which is used by some libraries.

Another benefit from mutable __proto__ is opportunity to operate only with own properties. For example if you want shallow copy of some object you can use:
function clone(obj) {
   var copy = {__proto__ : obj.__proto__};
   obj.__proto__ = {__proto__ : null};
   for (var i in obj) {
       copy[i] = obj[i];
   }
   obj.__proto__ = copy.__proto__;
   return obj;
}



_______________________________________________
es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to