Approach of new Object methods in ES5

Brendan Eich brendan at mozilla.com
Fri Apr 16 09:24:17 PDT 2010


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.


> And I have a question. Why ES5 give control on values of internal
> attributes? What will improve that? "Save" augmentation of built-in?

(You probably mean "Safe" here.)

> Good design of JS libraries?

All of these, but mostly to enable higher-integrity abstractions,  
including ones that mimic the built-in objects (including the DOM --  
more generally, all the notorious "host objects"; see also http://wiki.ecmascript.org/doku.php?id=harmony:proxies) 
.

We do not want the built-in objects to have all the power, including  
to make properties non-enumerable and non-configurable but writable  
(more on const below). The JS authors should have this power too, so  
the committee is not a bottleneck for innovation where such attribute  
control is necessary for integrity, emulation, or some other valid  
reason.


> Instead of that I want just naming convention improvements + `const`
> keyword as Mozilla implement.

Mozilla's 'const' does not allow you to make non-writable, non- 
configurable (without which, non-writable has zero integrity)  
properties of objects you create.

Mozilla's 'const' has other issues, but these will be fixed in  
Harmony. See http://wiki.ecmascript.org/doku.php?id=strawman:obj_initialiser_const 
  for more on Harmony ideas for 'const' as property initialiser keyword.

So a future 'const' can help, but it does not give enough control for  
emulations and other use-cases that need to control the enumerable  
attribute as well as writable and configurable.

Then there  is the object-level [[Extensible]] internal property,  
which 'const' does not cover in a general way in any Harmony proposal  
I have seen. One special form:

const foo() { ... }

would create a block-scoped non-writable binding, initialized by  
hoisting to the top of the block, whose value is the frozen function  
foo. This seems good, if a bit "DWIM" in doing several things at once.


> For example:
>
> myObj.CONSTANT = 3.14;
>
> And I expect property `CONSTANT` to have internat attributes
> {DontDelete), {ReadOnly}. But I forgot, Crockford suggest upper case
> only for global variables.

We're not able to introduce an uppercase-means-constant semantic rule  
at this point, it's too incompatible.

Conventions are just that, and without ES5's metaprogramming API they  
are advisory only -- again no integrity guarantees.


> If they was added new loop, misconseptions of JS library authors will
> be gone away. For example if there is:
>
> for own(var i in obj) {
>   //do something with next own property
> }

Not a bad idea! We've talked about it a bit in context of ECMA-357's  
popular (and separable from "E4X") "for each (var i in obj) ..." loop.

But it did not fit in ES5 with its "no new syntax not supported by 3  
of 4 browsers" guideline.


> And my last question is. Why do you change terminology in ES5? What
> was wrong with ES3 terminology?

Allen can field this one.

I will note that there are some real improvements in ES5, in  
particular to Chapter 10 which now uses declarative binding  
environments. ES1-3's abuse of objects for scopes (again I'm to blame  
for doing so in JS in1995, economizing on objects needed to implement  
the language in a big hurry) was a bug, not a feature.

/be


More information about the es-discuss mailing list