On Fri, Apr 16, 2010 at 09:06, Brendan Eich <[email protected]> wrote:
> On Apr 16, 2010, at 7:18 AM, Asen Bozhilov wrote: > > 2010/4/16, Dmitry A. Soshnikov <[email protected]>: >> >> 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
_______________________________________________ es-discuss mailing list [email protected] https://mail.mozilla.org/listinfo/es-discuss

