Approach of new Object methods in ES5

Erik Arvidsson erik.arvidsson at gmail.com
Fri Apr 16 10:11:03 PDT 2010


On Fri, Apr 16, 2010 at 09:06, Brendan Eich <brendan at mozilla.com> wrote:

> On Apr 16, 2010, at 7:18 AM, Asen Bozhilov wrote:
>
>  2010/4/16, Dmitry A. Soshnikov <dmitry.soshnikov at gmail.com>:
>>
>>  By the way, it is also petty that there's no ability to change prototype
>>> and there is only "get" function for that; __proto__ extension in this
>>> case was better.
>>>
>>
>> Especially when I want to change only [[Prototype]] and keep values of
>> other internal properties and methods for that object.
>>
>
> Sorry, I missed this in Dmitry's post (skimmed while traveling), but
> settable __proto__, apart from the object initialiser use case (i.e., on a
> new object not yet reachable, analogous to ES5's Object.create), is a
> terrible idea.
>
> I write this having designed and implemented settable __proto__ over 12
> years ago. At the time, unstratified metaprogramming APIs were popular; if
> it was good enough for Python, why not for JS. But the lack of
> stratification is a problem (consider JSON data with a key "__proto__"). And
> worse, the mutability means implementations must check for cyclic prototype
> chains in order to avoid ilooping.
>
> Mutable __proto__ also makes optimization harder, or simply defeats
> optimizations at the price of some complexity in the engine.
>
> Finally, mutating __proto__ on an existing object may break non-generic
> methods in the new prototype object, which cannot possibly work on the
> receiver (direct) object whose __proto__ is being set. This is simply bad
> practice, a form of intentional type confusion, in general.
>
> If specific cases wouldn't care because prototype-based methods are
> generic, setting __proto__ on an already-initialized object still smells
> like bad form, although I admit a Self-ish programmer would want it and
> probably use it well. But JS is not Self.


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();

When we have this code sample I'd like to also point out that using
__proto__ in an object literal is much more user friendly and more efficient
than using Object.create which is design for meta programming and not for
users.

Compare the following two:

var obj = Object.create(myPrototype,
getOwnProperties<http://www.google.com/codesearch/p?hl=en#2U3RyB59VC0/trunk/site/traits/files/traits.js&q=getOwnProperties%20traits%5C.js&sa=N&cd=1&ct=rc&l=90>
({
  ...
}));

and:

var obj = {
  __proto_: myPrototype,
  ...
};

It is pretty clear that Object.create was never designed for ordinary,
everyday use.

-- 
erik
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.mozilla.org/pipermail/es-discuss/attachments/20100416/7a6ba475/attachment-0001.html>


More information about the es-discuss mailing list