ES4 draft LAST CALL: Object

# Lars Hansen (17 years ago)

The only substantive change since the previous draft is a rename of createProperty to defineProperty in order to mirror the names defineSetter and defineGetter. The latter two are not in ES4 but in some browsers and could be expanded to accept additional flags to control enumerability and so on.

# Mark S. Miller (17 years ago)

2008/3/20 Lars Hansen <lhansen at adobe.com>:

The only substantive change since the previous draft is a rename of createProperty to defineProperty in order to mirror the names defineSetter and defineGetter. The latter two are not in ES4 but in some browsers and could be expanded to accept additional flags to control enumerability and so on.

  • I still prefer defineProperty (under whatever name) to be a static property rather than an instance property, so that an object can reliably perform this operation on itself without worrying about whether it is shadowed by an own property of the same name. As an instance method, to protect against this shadowing, one must instead write:

    Object.prototype.defineProperty.call(this, ...)

This is so much less convenient than the unsafe

this.defineProperty(...)

that people will get sloppy. Part of programming language design is to make the safer way also generally be the easier way. The innumerable places where

Object.prototype.hasOwnProperty.call(this, ...)

were or needed to be written should have already taught these lessons.

  • I also continue to think that any of the other alternatives for parameterizing defineProperty were more readable than a bunch of positional flag parameters whose order will often be mis-remembered. My favorite remains a C-style or-ing of bit flags, with manifest constants defining the bits.
# Lars Hansen (17 years ago)

-----Original Message----- From: Mark S. Miller [mailto:erights at google.com] Sent: 20. mars 2008 18:05 To: Lars Hansen Cc: es4-discuss at mozilla.org Subject: Re: ES4 draft LAST CALL: Object

2008/3/20 Lars Hansen <lhansen at adobe.com>:

The only substantive change since the previous draft is a rename of
createProperty to defineProperty in order to mirror the names
defineSetter and defineGetter. The latter two are not in ES4
but in some browsers and could be expanded to accept additional flags to control enumerability and so on.

  • I still prefer defineProperty (under whatever name) to be a static property rather than an instance property, so that an object can reliably perform this operation on itself without worrying about whether it is shadowed by an own property of the same name. As an instance method, to protect against this shadowing, one must instead write:

    Object.prototype.defineProperty.call(this, ...)

This is so much less convenient than the unsafe

this.defineProperty(...)

that people will get sloppy.

Another interesting point. Probably, the intrinsic defineProperty method ought to be declared 'final' at a minimum, it does seem somewhat senseless to allow it to be overridden.

At that point, 'this.intrinsic::defineProperty(...)' is always predictable, though wordier than Object.defineProperty(...) would be.

I can't imagine anyone using the longer version you provide above. How unsafe should I feel? (I'm not being sarcastic, for the record.)

Part of programming language design is to make the safer way also generally be the easier way. The innumerable places where

Object.prototype.hasOwnProperty.call(this, ...)

were or needed to be written should have already taught these lessons.

  • I also continue to think that any of the other alternatives for parameterizing defineProperty were more readable than a bunch of positional flag parameters whose order will often be mis-remembered. My favorite remains a C-style or-ing of bit flags, with manifest constants defining the bits.

I suspect "often" is overstating the case, but I'm not really arguing, other alternatives would be somewhat easier to use. They would also break existing patterns, and IMO that's where the balance comes in.

# P T Withington (17 years ago)

The ! here appears to be a type-oh:

# Lars Hansen (17 years ago)

It is. Thanks.

# Nathan de Vries (17 years ago)

I much prefer Yuh-Ruey Chen's suggestion of rolling the last three
arguments of createProperty into a single bitmask argument:

public dynamic class Object { static const READ_ONLY: AttrToken = new AttrToken; static const DONT_DELETE: AttrToken = new AttrToken; static const DONT_ENUMERATE: AttrToken = new AttrToken;

 intrinsic function __createProperty__(name, value, mask) : void …

}

function Foo() { this.__createProperty("bar", [], Object.READ_ONLY &
Object.DONT_DELETE & Object.DONT_ENUMERATE); }

In terms of extensibility & call-site readability, this seems like
the way to go for me.

Cheers,

-- Nathan de Vries

# Nathan de Vries (17 years ago)

On 22/03/2008, at 1:36 AM, Nathan de Vries wrote:

Object.READ_ONLY & Object.DONT_DELETE & Object.DONT_ENUMERATE

Whoops, please excuse the cludge. It's 2.00am here, and I'm sure you
knew what I meant.

Cheers,

-- Nathan de Vries

# Brendan Eich (17 years ago)

On Mar 20, 2008, at 6:05 PM, Mark S. Miller wrote:

  • I still prefer defineProperty (under whatever name) to be a static property rather than an instance property, so that an object can reliably perform this operation on itself without worrying about whether it is shadowed by an own property of the same name. As an instance method, to protect against this shadowing, one must instead write:

    Object.prototype.defineProperty.call(this, ...)

This is so much less convenient than the unsafe

this.defineProperty(...)

that people will get sloppy. Part of programming language design is to make the safer way also generally be the easier way. The innumerable places where

Object.prototype.hasOwnProperty.call(this, ...)

were or needed to be written should have already taught these lessons.

I agree completely, based on Narcissus experience -- see:

lxr.mozilla.org/mozilla/search?string=defineProperty

in particular

lxr.mozilla.org/mozilla/search?string=hasDirectProperty

Thanks for pointing this out.

The long-standing Mozilla defineGetter, defineSetter, etc.,
if they were to be standardized, could also be rephrased as Object
"static methods". In ES4 terms these would be final and static, so
fixtures.

  • I also continue to think that any of the other alternatives for parameterizing defineProperty were more readable than a bunch of positional flag parameters whose order will often be mis-remembered. My favorite remains a C-style or-ing of bit flags, with manifest constants defining the bits.

Agreed again -- Narcissus's defineProperty used dontDelete,
readOnly, dontEnum trailing booleans, which at least initially helped
by allowing the most common cases to leave off trailing arguments.
But I could never remember which was which, reading opaque triples of
boolean values in call sites.