Proposal: Object.defineProperty shorthand

Sean Eagan seaneagan1 at gmail.com
Thu May 26 11:37:42 PDT 2011


Note: This proposal stems from the discussion in [3].  The intention
is to update [1] and [2] and either include the new content within [1]
or a new strawman linked to from [2].

Object.defineProperty shorthand
==========================

Object.defineProperty calls are verbose, and also require property
descriptor object allocation and validation.  Both of these issues
could be solved by providing concise and optimizable syntax for this
functionality.  Allen Wirf-Brock's "Concise Object Literal Extensions"
strawman [1] already solves this within the context of object
literals, however, its infix non-writable mark makes it non-applicable
to other contexts.  This can be fixed by making it a prefix, and
adjusting the prefix-character to property-descriptor-attribute
mapping.

Semantics:

// # implies non-configurable
# a.b = c
// <=>
Object.defineProperty(a, "b", {configurable: false, writable: true,
enumerable: true, value: c})

// ! implies non-writable, ~ implies non-enumerable
// all assignment operators can be used
! a.b += c
// <=>
Object.defineProperty(a, "b", {configurable: true, writable: false,
enumerable: true, value: a.b + c})

// postfix expressions only work when # (non-configurable) is used
!~a.b++
// <=>
!(~(a.b++))
#~a.b++ // evaluates to initial value of a.b just like a.b++ does
// <=>
Object.defineProperty(a, "b", {configurable: false, writable: false,
enumerable: true, value: a.b++})

// can use both dot and bracket syntax
#!~ a[b] = c
// <=>
Object.defineProperty(a, b, {configurable: false, writable: false,
enumerable: false, value: c})

// destructuring works as well
[#a.b, !this[c], ...~d.e] = [1, 2, 3, 4];
// <=>
Object.defineProperty(a, "b", {configurable: false, writable: true,
enumerable: true, value: 1});
Object.defineProperty(this, c, {configurable: true, writable: false,
enumerable: true, value: 2});
Object.defineProperty(d, "e", {configurable: true, writable: true,
enumerable: false, value: [3, 4]});

// changes to object literals
var a = {
  #!~b: "b" // infix = changed to prefix !, previous ! changed to #
  !c // non-writable implicit initialization parameters now work
}


Grammar changes to [2] :

LeftHandSideExpression :
  DataPropertyPrefixopt BasicLeftHandSideExpression

BasicLeftHandSideExpression :
  NewExpression
  CallExpression

PrefixedPropertyAssignment:
  DataPropertyPrefixopt DataPropertyAssignment
  AccessorPropertyPrefixopt AccessorPropertyAssignment

Note: the following two replace PropertyPrefix

DataPropertyPrefix :
  !
  AccessorPropertyPrefix
  AccessorPropertyPrefix !
  ! AccessorPropertyPrefix

AccessorPropertyPrefix :
  #
  ~
  ~#
  #~

Note: the following two replace PropertyAssignment

DataPropertyAssignment :
  Identifier
  PropertyName : AssignmentStatement
  PropertyName ( FormalParameterListopt ) { FunctionBody }

AccessorPropertyAssignment :
  get PropertyName ( ) { FunctionBody }
  set PropertyName ( PropertySetParameterList ) { FunctionBody }
  set super get PropertyName ( ) { FunctionBody }
  get super set PropertyName ( PropertySetParameterList ) { FunctionBody }


[1] http://wiki.ecmascript.org/doku.php?id=strawman:concise_object_literal_extensions
[2] http://wiki.ecmascript.org/doku.php?id=strawman:basic_object_literal_extensions
[3] https://mail.mozilla.org/pipermail/es-discuss/2011-May/014566.html

Thanks,
Sean Eagan


More information about the es-discuss mailing list