Mark Caudill

Like any good programmer, I’d like to stay on top of any changes planned for programming languages that I use (or scripting languages).  So when I heard about EcmaScript 5th Edition (near final draft) being released, I wanted to get all of the juicy details on what to expect.  As it turns out, this hasn’t been documented really well yet: so I did the better thing and read the draft.

There are some really exciting things to come, some of the biggest being to the foundation Object object’s functions which will allow turning off Enumeration on properties, making “read only” properties, etc. I’ve noticed a lot of this has come from Mozilla’s innovation and also I see some similarities to PrototypeJS’s modifications to prototypes.

JSON object

The first major addition in the draft is the JSON object, which is not a constructor but rather similar to the Math object and some of Object’s functionality.  JSON.parse takes a JSON string and creates an object.  JSON.stringify takes an object and creates a string.  Pretty simple!
JSON.parse has an optional 2nd parameter (a function) that receives a key and value which it can return a value to override the original value.
JSON.stringify has an optional 2nd and 3rd parameter. The second being a function to modify the way objects and arrays are stringified or an array of white listed keys to stringify.  The third being a string or number that allows the result to have a singular space or up to 100 spaces (and line feeds) between keys of the object.

Object object

  • Object.getPrototypeOf(O) returns the prototype of O if O is an Object.
  • Object.getOwnPropertyDescriptor(O, P) returns the property descriptor of O’s (as object) property P (as property of O).
  • Object.getOwnPropertyNames(O) returns an array of property names (uses ToString on the names).
  • Object.create(O[, Properties]) returns an object with a prototype of O and properties according to Properties (as if called through Object.defineProperties).
  • Object.defineProperty(O, P, Attributes) returns O after adding a new property P with a property descriptor of Attributes. Just imagine the possibilities when O is a DOM element :). Read: DOM Prototypes Part 1 (Intro), Part 2
  • Object.defineProperties(O, Properties) returns O after enumerating Properties as name/descriptor (e.g. {name: descriptor}).
  • Object.seal(O) returns O after setting the internal Configurable flag to false for each property of O and the internal Extensible property of O to false.
  • Object.freeze(O) returns O similar to seal except the internal Writable flag is also set to false.
  • Object.preventExtensions(O) returns O after setting the internal Extensible property of O to false.
  • Object.isSealed(O) returns boolean based on all properties’ Configurable (any true returns false) and O’s internal Extensible property (a false returns true).
  • Object.isFrozen(O) returns boolean similarly to isSealed except Writable is checked (any true return false).
  • Object.isExtensible(O) returns boolean value of the internal Extensible property of O.
  • Object.keys(O) returns an array of property names.

Function object

Function binding!  Now this is based on whatever you bind a function to or whatever this internally would be by default.  What that means for us is that we can bind functions easily to objects via the prototype so that calling this in those functions returns the associated object. Function.prototype.bind(this[[, arg1] arguments…]) where arg1/arguments are passed into the function first.

See: PrototypeJS’ implementation

Array object

Array.isArray(arg) returns boolean based on if the internal Class property is “Array”.

  • Array.prototype.indexOf(needle[, fromIndex]) returns the position of needle in the array, if not return -1 is returned.  If fromIndex is positive or 0 (defaults to 0) this is the start index; if it is negative fromIndex is the offset from the end of the array to begin searching.
  • Array.prototype.lastIndexOf(needle[, fromIndex]) returns similarly to indexOf except the array is searched reversely.
  • Array.prototype.every(callFunc[, thisArg]) returns boolean depending on callFunc’s return value via iterating the array.  If thisArg is specified, the function is bound to thisArg, otherwise thisArg defaults to undefined.  callFunc gets three arguments for each element in the array: value, count, the object of this (not what thisArg is!).
  • Array.prototype.some(callFunc[, thisArg]) returns boolean similarly to every except one true instance returns true.
  • Array.prototype.forEach(callFunc[, thisArg]) returns nothing, but processes similarly to some and every.
  • Array.prototype.map(callFunc[, thisArg]) returns a new array of return values by processing similarly to forEach.
  • Array.prototype.filter(callFunc[, thisArg]) returns a new array of elements that callFunc returns true while processing (similarly to the processing of forEach).
  • Array.prototype.reduce(callFunc[, initialValue]) returns a value that is daisy-chained through callFunc by passing accumulator, property value, index, and the object.  The return value of callFunc is passed into the next call as accumulator, then accumulator is returned.  initialValue sets the starting accumulator, otherwise this starts at index 1 (2nd element) with an accumulator of index 0.
  • Array.prototype.reduceRight(callFunc[, initialValue]) returns similarly to reduce except from right-to-left in the array (last to first).

String, Number, Boolean, Date

Date.now() returns a Number with a unix timestamp.

  • String.prototype.trim() returns the value of this without white space on the left or right.
  • Date.prototype.toISOString() returns a string representing the time in the Date Time string format as UTC.
  • String.prototype.toJSON(key), Boolean.prototype.toJSON(key), Number.prototype.toJSON(key), Date.prototype.toJSON(key) returns a string that represents object.  Does anyone have some ideas on what key actually does for this?

Miscellaneous

Of importance is that Unicode 3.0 is now supported, including relevant whitespace additions.

Line terminator characters proceeded by an escape sequence (\) are allowed in a string.

Indirect calls to eval use the global (window) environment.

For-in doesn’t throw errors for null/undefined, instead it just continues as if it was given an object that had no enumerable properties.

Strict Mode was added, but I’m unsure if we’ll see this in JavaScript (see Annex C; page 237).

New keyword debugger is moved from future reserved words to keywords and allows triggering a breakpoint when running within a debugger, otherwise it should have no observable effect.

The Object object is now setup drastically different internally: ReadOnly becomes “Writable”, DontEnum becomes “Enumerable”, DontDelete becomes “Configurable” (also only allow some changes; with exceptions, see 8.6.1). “Set” was also changed from Put and is by default an undefined function. Most of this can be written over using property descriptors (see Object.defineProperty above).

(A lot more miscellaneous stuff, see Annex E for upgrade breakers.)

Suggestions? Comments?

Thank you ECMA :). Hope to see all of this implemented in a year or two (since IE8 in standards mode and Firefox 3.1 are to support at least portions of this) as part of JavaScript. Is there anything else you think should be in this post? Comment!

13 Replies »

  • I always found it strange that ‘arguments’ is an object and not an Array. having all of these new Array methods is really neat, but can be rather furstrating if you can’t use them on the arguments your function just received.

    So has this been changed too?

    Reply by Konrad Zielinski — April 14, 2009 @ 5:55 pm

  • Konrad: Arguments is a special object still, but…

    *Edit: See Bredan’s post below, he explains that arguments now uses the Array.prototype but is still a “special class” of an object*

    Reply by Mark Caudill — April 14, 2009 @ 6:22 pm

  • arguments.callee is usefull. but arguments could have still just being an Array with an extra property rather then a completely unrelated object which just happens to behave the same, some of the time (you still have arguments.length). Ditto for Strings.

    The other question being, once the draft gets accepted how long will it be before we see support in all of the wonderful new JavaScript engines.

    Reply by Konrad Zielinski — April 14, 2009 @ 6:52 pm

  • [...] Or more like an upgrade. Mark Cuadill has more to say about it. [...]

    Pingback by JavaScript is getting a facelift. — April 14, 2009 @ 7:49 pm

  • [...] Originally posted here: Mark Caudill, a ninja in waiting » JavaScript New Features … [...]

    Pingback by Mark Caudill, a ninja in waiting » JavaScript New Features … — April 15, 2009 @ 2:01 am

  • Konrad@5:55pm - ES5 does make arguments have Array.prototype in its prototype chain, a change from ES1-3. So you can say arguments.slice(0,2), e.g., and not the overlong Array.prototype.slice.call(arguments,0,2).

    Coming in ES Harmony: rest parameters, as drafted for ES4: function foo(fst, snd, …rest) { /* here rest is a true Array instance */ }. To match, the “spread” operator: given an Array arr, you can spread it out so its elements are passed as positional parameters to a function foo, via foo(…arr). With rest and the spread operator, one can compose new and apply without a hardcoded newApply method, and the need for arguments goes away.

    /be

    Reply by Brendan Eich — April 18, 2009 @ 12:05 am

  • Brendan: Thanks for the correction! I did look at the spec but I overlooked 10.5 CreateArgumentsObject #5, I only saw the argument getting the Arguments class.

    Alo, harmony looks exciting as well, but the fact that ES5 is already making motions to implementation really make the immediate future promising. I can see a year from now us having a “ES5-rollup” library (in Javascript) that attempts compatibility when using “ES3.” Great things to come no matter what though.

    Reply by Mark Caudill — April 18, 2009 @ 8:04 am

  • Thanks for the list. It looks like some of the toJSON methods got cut?

    I didn’t happen across an “ES5-rollup” library, so I started one.

    http://bitbucket.org/JustinLove/es5/

    Reply by Justin Love — December 13, 2009 @ 9:12 am

  • “Unicode 3.0″? Wow, that’s very up-to-date… :-(

    Reply by xurfa — January 15, 2010 @ 1:28 pm

  • @Konrad: You’ve always been able to call Array methods on an arguments object. Just call it directly from Array’s prototype, but invoke it upon the arguments object using “call” or “apply”:

    var secondArgOnwards = Array.prototype.slice.call(arguments, 1);

    Reply by Animal — January 19, 2010 @ 8:20 am

  • Nice stuff, though part of me simply can’t believe there’s _still_ no analogue for sprintf() in javascript…

    Reply by jL — January 19, 2010 @ 11:13 am

  • It seems like ecma 5 is a backtrack from the stricter ecma 4 standard. I guess we have Microsoft to blame for that one… It’s a shame because if we bit the bullet and added things like namespaces and strict typing, then we’d have some real speed increases. Speed is going to be key, what with everything going mobile and to some degree renouncing flash. Have you tried to run anything vaguely complex in javascript on a phone. You can’t really do that much. I guess things like ‘freeze’ will add some speed by helping with encapsulation, but they could do so much more. Oh well, the web was never one to evolve that quickly.

    Reply by Sundev Lohr — February 17, 2010 @ 2:05 pm

  • This was true in april-2009 draft, but in final version (december 1009)

    arguments

    isn’t Array:

    10.6. Arguments Object

    4. Set the [[Class]] internal property of obj to “Arguments”.
    5. Let Object be the standard built-in Object constructor (15.2.2).
    6. Set the [[Prototype]] internal property of obj to the standard built-in Object prototype object (15.2.4).

    Reply by joseanpg — February 27, 2010 @ 2:21 pm

RSS feed for replies on this post. TrackBack URL

Leave your reply