On Fri, Apr 16, 2010 at 7:11 PM, Erik Arvidsson <[email protected]>wrote:
> > > 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 > > There is of course a very simple alternative to accessing "internal" properties like [[Prototype]] et.al. You could introduce a simple syntax using a new unused currently forbidden character into the language. To be honest, foo.bar#Prototype would be something that spring to mind. I know Mozilla uses it for sharp variables, but formally, the hash is not part of ES (yet). Of course other characters could be used here. A special char that indicates attribute access, like the dot does for property access. This could not break any scripts... - peter
_______________________________________________ es-discuss mailing list [email protected] https://mail.mozilla.org/listinfo/es-discuss

