ECMAScript 5 was recently released, a full 10 years after the previous version of the language came out. After all this time, the updates are not groundbreaking, but they are useful.
Edition 3 of the language was released in 1999, and there never was an Edition 4. The committee designing the language basically split into two warring (or at least severely disagreeing) factions, each wanting to take the language in a different direction.
One of these directions was incredibly ambitious, and included modules and classes. However, due to disagreements (as well as valid arguments from both sides), the group released a much less ambitions edition, which we now see as Edition 5.
There are plans for another version in the future that will implement some of the more exciting features. The working name for this edition is Harmony because the warring groups can work in, well, you get the picture (Wikipedia has a nice entry on what exactly went down during the ECMAScript wars, with much more detail than I have room for).
Edition 5 Lowdown
Before covering what exactly Edition 5 gives us, it’s important to remember one thing: Currently, no browsers support it. Edition 5 has been published as a final draft, and it probably won’t be approved until late 2009 as an official specification.
And, only after browsers fully support the language will programmers be able to take full advantage of the new language features. However, you don’t have to wait as long as you might think. Internet Explorer Version 8.0 includes many of the language’s new features already, and other browsers will have the features soon, as well.
The updates to the language are not particularly shocking or exciting. Rather, the updates are modest and useful, simplifying some of the programming, particularly in areas where developers usually relied on third-party libraries.
For starters, the language includes a new strict mode feature. Technically speaking, strict mode is a subset of the language. When running in strict mode, the runtime engine will not allow certain aspects of the language to function-aspects that could result in buggy programming. For example, the with statement is particularly useful for writing shorthand code. Under strict mode, however, you cannot use the with statement.
That, of course, is not to say the language has a buggy feature. The with statement isn’t buggy; rather, it’s easy for a sloppy programmer to write buggy code if relying too heavily on the with statement. Now, certainly, programmers should know their own abilities, and can therefore decide if they want to write code for the strict mode or not.
Next up is full built-in support for the JSON protocol. Programmers always need a way to store and transfer data. Often, XML is the preferred format for storing the data. However, XML must be parsed, and then data structures must be built based on the contained data.
JSON data can be easily stored on a Web server in text files or in a database. Using AJAX, an ECMAScript program can retrieve the data and evaluate it.
With Edition 5 of ECMAScript, this function is built right into the language. The language has a new object called JSON, which includes only two functions: parse and stringify. Now, instead of risking security with eval and instead of relying on third-party libraries, you can simply call JSON.parse to parse your JSON data safely. And if you have data that you want formatted as JSON text, you can call JSON.stringify.
The JSON.parse function recognizes a limited subset of the ECMAScript language. The specification includes the grammar of this subset. If text is passed in that does not conform to the grammar in this subset, a syntax error is returned.
Although JSON is useful, one reason many programmers prefer XML is you can transform the data as you’re parsing it, filtering out only certain aspects of it.
For example, you might have an XML file that contains a list of customers. Each customer might have a name, address and phone number. You might want just a list of names and phone numbers, skipping the addresses. You could fully process the XML and end up with a list of objects containing names, addresses and phone numbers, and then ignore the addresses. Or you could manually walk through the XML data, picking out only the names and phone numbers. Or, if you’re an XML guru, you would likely use a transform. Using declarative programming, you would specify what the transformed XML looks like. The XML library would take the existing XML and automatically transform it into a different XML-in this case, XML that contains only names and phone numbers of the customers. Then you could parse the resulting XML. That sounds complicated, but it’s actually easier when done correctly.
The designers of Edition 5 of ECMAScript were obviously aware of the need for transformations. As such, they included in the specification an optional parameter to the JSON.parse function called a reviver, which is a function you pass into parse that lets you filter and transform the data. This means programmers familiar with XML will likely find JSON to be similar in power. (I should note, however, that this reviver concept isn’t actually new. Open-source libraries already exist that give you a JSON object with a stringify function and a parse function that supports a reviver. Here’s a page that gives you more information, including a link to the open-source library.)
Object Enhancements: Setters and Getters
Edition 5 also includes enhancements to objects themselves.
Perhaps one of the most controversial enhancements is that of property getters and setters. These are essentially functions that you can call for setting and retrieving object members. But the difference between these functions and regular functions is you use syntax that looks like setting and getting the values themselves.
In other words, instead of calling myObject.SetX(10), you can simply use myObject.X = 10. This code will have the effect of calling the setter function.
The reason this is controversial is that some programmers feel such code can result in bugs. They argue that if one programmer is writing a library of code that includes property getters and setters, another programmer might not be aware that calling myObject.X = 10 is actually calling a function, and the function can do what it pleases, possibly changing the 10 to something else.
The opposing argument, however, is that a good programmers should know the library they are using. If programmers are providing a library that includes getters and setters, they should make it clear in the documentation how those functions work. And the programmers using the library should read the documentation and be aware of the design. (I tend to be in the latter camp. I feel that programmers making use of good documentation should be able to correctly use the getters and setters.)
In the specification, properties of an object that can be accessed through getters and setters are called named accessor properties. Such properties have a name, as well as accessor functions (a getter and a setter) associated with them.
I mentioned that IE 8 includes some of the new Edition 5 features. If you’re interested in learning more about the named accessor properties and want to try them out, check out this article.
In addition to getters and setters, the Object object itself includes several new functions. Some allow you to manipulate the getters and setters of other objects (by passing the object as a parameter); some let you create sealed and frozen objects. (Sealed objects are objects whose properties cannot be deleted or have their attributes changed. Frozen objects are sealed objects with the further restriction that their property values cannot be changed.)
For a nice rundown of the new Object features, check out this page.
The single biggest enhancement to functions is the ability to bind a function to an object, effectively making it become a member of the object. Then, if the function uses the this keyword, this will refer to the object (not the function itself).
In ECMAScript, functions are treated as objects (with the additional feature that they can be called). When you create a new function, you are creating an object based on the built-in Function object. From this Function object, your new function inherits various members (through what’s called its prototype). Edition 5 includes one new member in the Function prototype that all your functions will inherit: bind. This new member is itself a function that you can call to bind the function to an object.
In other words, when you have a function, you can call the function’s bind function. Pass in an object, and the function will become a member of that object. The object now has a member function identical to the function you started with.
Now, technically speaking, the function itself hasn’t changed. It’s still there and you can use it. Instead, the ECMAScript engine creates a new function identical to the original in all ways, except that new function is now a member of the object.
There are also several smaller enhancements to ECMAScript.
I already mentioned the handful of new functions that exist on the main Object object. The Array object now includes in its prototype several handy new functions that will make your array-manipulation life easier (such as indexOf, map, filter and others). Strings now include a trim function, and the basic objects String, Boolean, Number and Date now include prototype functions for converting to JSON strings. To see the full list, check out the page I mentioned earlier.