Controlling DontEnum (was: ES4 draft: Object)

Lars Hansen lhansen at adobe.com
Thu Mar 13 12:19:20 PDT 2008


> -----Original Message-----
> From: peterjoel at gmail.com [mailto:peterjoel at gmail.com] On 
> Behalf Of Peter Hall
> Sent: 13. mars 2008 12:38
> To: Lars Hansen
> Cc: Kris Zyp; es4-discuss at mozilla.org
> Subject: Re: Controlling DontEnum (was: ES4 draft: Object)
> 
> Is there enough value in complicating matters by adding the 
> ability to set dontDelete and readOnly? You can create 
> non-deletable properties by using a class or record type, and 
> you can create read-only properties by adding a get function 
> without a corresponding set...
> 
> Are there any use cases where these solutions won't cover it?

Depends on your point of view.  I wrote a paper on evolutionary
programming in ES4 (available from ecmascript.org), which demonstrates a
progression from ES3 style code to ES4 style code with various stops
along the way.  One of the holes in that story is that it's not possible
to make the properties introduced in a function-style constructor
anything but enumerable, deletable, and writable:

  function Server(host) {
    this.host = host
    this.database = []
  }

Both these fields are supposed to be constant, and there's no reason for
them to be enumerable.  The paper shows how you can use a user-defined
namespace to make them inaccessible (non-public namespaced properties
are not enumerated, and if the namespace is hidden from client code --
not always easy -- then the field can't be accessed or deleted), but
it's clearly a bit of a hack in that it is a consequence of other design
choices in the language.  The direct approach would set the properties
explicitly:

  function Server(host) {
    this.__createProperty__("host", host, true, true, true);
    this.__createProperty__("database", [], true, true, true);
  }

So this is a use case if you believe that relatively fine-grained
evolution from ES3 style to ES4 style is a feature of the language.  (I
do.)

There are declarative ways of solving the problem -- essentially
annotating the function, saying "this is a constructor function and the
fields named such and so are going to have these and those attributes",
but they add yet more features to an already fairly feature-laden
language.

(One proposal goes like this:

  constructor function Server(host) : { const host: string, const
database: array } {
    this.host = host
    this.database = []
  }

and it's not all that heavyweight, but it's a new, ad hoc feature all
the same.)

I'm mostly agnostic about __createProperty__ being able to set
DontDelete and ReadOnly; DontEnum is the really important one.  At the
same time, it seems silly not to just solve the general problem when we
have a chance.  Just because you can't enumerate a property doesn't mean
that you -- or a library you import -- can't accidentally -- or
maliciously -- overwrite it.

--lars



More information about the Es4-discuss mailing list