ECMAScript 5 – the current JavaScript standard

ECMAScript is THE language of the web and yet many developers aren´t even aware of its existence.

It is a standard (named ECMA-262) developed by Ecma International that serves as a standardized basis for the likes of JavaScript, JScript or ActionScript. The different often called “JavaScript engines” like V8 (Google Chrome), SpiderMonkey (e.g. Firefox), JavaScriptCore (Safari) or Chakra (JScript engine – Internet Explorer) can therefore be regarded as implementations of ECMAScript.

Although all different implementations are obviously based on the official ECMAScript specification, they all include some minor aspects or behavior (or additional features) that were not standardized.

Most people use to rely on the term ‘JavaScript’ because it is way more popular but in fact they often talk about ECMAScript.

The current version of ECMAScript is version 5. This article will introduce the new features added by the 5th edition.

Browser compatibility

Regarding the browser/JavaScript engine support for ES5, all features are supported since Firefox 4, Chrome 19, Safari 6, Opera 12.10 and Internet Explorer 10. It is worth mentioning that IE9 already supports everything except strict mode, which is not a serious problem as strict mode is silently ignored.

Many features were already supported in prior browser versions. Detailed information can be found at this excellent reference.

Quick history

After JavaScript and Netscape Navigator were released by Netscape and Brendan Eich in 1996, Microsoft decided to develop an own dialect (e.g. to avoid trademark issues) of the language for their Internet Explorer, named JScript.

By the end of 1996, Netscape decided to hand the language to Ecma International in order to create a standardized specification that both, Netscape and Microsoft, could rely on for further developments of their scripting languages.

The last ECMAScript version that was completely supported by all modern browsers is the 3rd, which was released in 2001. After version 4 was completely abandoned, the 5th version of ECMAScript, released in 2009, introduced a bunch of new features. ECMAScript 5.1 (2011) didn´t provide any new features and was mostly a maintenance release clarifying some ambiguous specification statements introduced with the 5th version.

New features of ECMAScript 5

Although the standard was passed in 2009, many people don´t know or at least don´t use the features introduced by ES5 yet. This is quite a pity because the features can vastly improve the code quality and can reduce the probability of errors. All in all those new features make JavaScript a better language, especially for larger projects.

Strict mode

Strict mode is basically a subset of JavaScript, omitting the most critical and error-prone parts of JavaScript. This is inter alia achieved by throwing errors for code that would have been accepted without strict mode.

To use strict mode you simply have to include


"use strict";

in your program.

Impacts of strict mode:

    • No creation of global variables inside methods:
// creating a global variable (on accident)
// inside a method
function foo () {
    someVar = 1;    // normally creates a global variable
                    // causes an error in strict mode
}

    • The with()-statement is forbidden
    • Restrictions for eval() und arguments
      • Almost every usage of eval() causes an error
      • The arguments property of a method may not be accessed
function foo() {
    bar.arguments = [1, 2, 3];
    // causes an error in strict mode
}
  • Unique parameter and object literal properties names
// identical names for parameters and for properties
// in object literals
// previously allowed, causes errors in strict mode
function identicalNames(param, param) { // error
    var obj = { foo: "bar", foo: "foo"};    // error
}

    • No octal numbers
// usage of octal numbers
function octal() {
    alert(42 == 052);   // normally prints true
                        // causes an error in strict mode
}

It is NOT recommended to enable strict mode globally in your project because this would affect included 3rd party libraries and could very well break them.

One solution would be to include “use strict” in every single method, but this would be very tedious and would presumably be forgotten once or twice in a big project.

If you follow Douglas Crockford´s advice from his acclaimed book “JavaScript – The Good Parts” however and use only a single global variable as a kind of ‘container’ for your whole application, you can use a self-invoking anonymous function to apply the strict mode to all of your methods without polluting the global namespace and without forcing the strict mode for included 3rd party libraries.

var MYAPP = {};
(function(){
    "use strict";

    MYAPP.someFunction = function() {
        someUndeclaredVariable = 42;      // error
    };

    MYAPP.anotherFunction = function() {
        console.log(42 == 052);     // error
    };
})();

Property descriptor maps

JavaScript allows you to dynamically add new properties to an object any time you want and to change or to delete existing ones. While this may seem useful at times it surely is always a probable part to break a program.
With the property descriptor maps introduced in ES5 you can now specify how the properties of your object can be altered after creation.


var obj = {};
Object.defineProperty(obj, ‘attr’, {
    value: 1,
    writable: true,
    enumerable: true,
    configurable: true
});

  • Value: The intrinsic value of the property
  • Writable: can the value of the attribute be changed after being set?
  • Enumerable: Specifys if the property may be iterated on for example in for-loops
  • Configurable: Specifys if a property can be deleted and how the values of its property descriptor map can be modified

Getters and Setters

An additional nice feature that comes with the property descriptor maps is the ability to implement getter and setter like methods for the properties of your objects. The “get” method will be called every time the property is accessed, the “set” method every time the value of the property is changed.

Please note that properties with a getter and setter are no normal object properties and may not have an intrinsic value. You therefore could not include a get or set method in the previous property descriptor maps code example.

Thus you have to e.g. create a property “value” with a getter and setter to manipulate the (private) property “_value”. With another self-invoking anonymous function and thanks to closures you can create a private field “_value” that can only be accessed through the getters and setters of “value”.

var obj = {};
(function (){
	var _value = 1;
	Object.defineProperty(obj, "value", {
		get : function(){
			console.log("accessing _value");
			return _value;
		},
		set : function(newValue){
			console.log("changing _value to: " + newValue)
			_value = newValue;
		}}
	);
})();

console.log(obj.value);
obj.value = 5;
console.log(obj.value);

//  prints...
//    accessing _value
//    1
//    changing _value to: 5
//    accessing _value
//    5

Further new methods for objects

  • Object.preventExtensions()

Prohibits to add new properties to an object

var obj = {foo: "foo"};
obj.bar = "bar";
Object.preventExtensions(obj);
obj.someVar = "123";    // error

  • Object.seal()

Sealed objects may not be extended with new properties and exisiting properties may not be deleted

  • Object.freeze()

In addition to ‘sealed’ objects, freeze() also prohibits to change the values of the property descriptor map of any property of the object, resulting in an immutable object.

Native JSON support

Since of ECMAScript 5 there is also native JSON support. Ecma International took notice of what some JavaScript frameworks did and standardized two methods:

  • JSON.parse()

Converts a JSON string into a JavaScript object


var fromJSON = JSON.parse( '{"var1":"foo","var2":"bar"}' );
console.log(fromJSON.var1 + " - " + fromJSON.var2);
// prints foo - bar

  • JSON.stringify()

Converts a JavaScript object into a JSON string


var obj = {
    var1: "foo",
    var2: "bar"
};
console.log(JSON.stringify(obj));
// prints {"var1":"foo","var2":"bar"}

Convenience methods for arrays

There are also some new convenience methods for arrays that were mostly (similar to the JSON additions) adapted from JavaScript libraries.

  • Array.isArray(someVar);

The typeof operator already exists for a long time in JavaScript. Unfortunately it doesn’t really work with arrays:

var anArray = [1, 2, 3];
console.log(typeof anArray);    // prints 'object'

Although this is no bug (because arrays in JavaScript are internally treated and represented as objects with normal property key: value pairs) it surely doesn’t help much. This is why Array.isArray() was added to ES5.


var anArray = [1, 2, 3];
console.log(Array.isArray(anArray)); // prints 'true'

  • forEach()

Is used to iterate on an array and to apply a callback function on every element


var anArray = [1, 2, 3];
anArray.forEach(function(x){
console.log(x * 3);     // prints 3, 6, 9
  • map() and filter()

Map() basically works like forEach() with the difference being that in contrast to forEach(), where only a function is invoked on every method, map() returns a new array with all elements after the callback function was applied to them.
Filter() expects a callback function returning true for elements that should be included in the new array and false for elements that should be discarded.


var anArray = [1, 2, 3, 4, 5, 6];
var squared = anArray.map(function(x){
    return x * x;
});
squared.forEach(function(x) {
    console.log(x);     // prints 1, 4, 9, 16, 25, 36
});

var oddOnesOut = anArray.filter(function(x){
    if(x % 2 == 0) {
        return true;
    } else {
        return false;
    }
});
oddOnesOut.forEach(function(x) {
    console.log(x);     // prints 2, 4, 6
});
  • every() and some()

Like filter() these methods also expect a callback method intended to test an element and to return true if the element passes the test and otherwise false. Every() returns true if the callback method returned true for all elements in the array, otherwise false, some() returns true if the callback passed for at least one element.


var anArray = [10, 100, 1000];
console.log(anArray.every(function(x){
    return x % 10 == 0;
    //prints 'true' because every element is a multiple of 10
}));

console.log(anArray.every(function(x){
    return x > 500;
    //prints 'false' because NOT every element is
    //greater than 500
}));

console.log(anArray.some(function(x){
    return x > 500;
    //prints 'true' because at least one element is
    //greater thant 500
}));

  • reduce()

Reduce() is a method that invokes a callback on every element and returns a single element. For this purpose the callback methods expects an element of the array and as a second parameter the returned result of the previous element.
Reduce() is handy for example to calculate the sum of all elements or to find the maximum/minimum.


var anArray = [9, 3, 5, 13, 2, 4, 11];
console.log(anArray.reduce(function(elem, prev){
    return elem > prev ? elem : prev;       // prints 13
}));

Minor Date enhancements

The Date object also got some nice little additions. A Date.now() method was included to get the passed seconds since 1.1.1970 (which is easier to read/write and about twice as fast as the old approach “new Date().getTime()”).

var start = Date.now();
window.setTimeout(function(){
		var end = Date.now();
		console.log("Computation took "
                + (end - start) / 1000 + " secondsn")
	}, Math.random() * 1500
);

Additionally there is also a “toISOString” method:

var iso = new Date().toISOString();
console.log(iso);
// prints for example 2013-03-26T16:35:42.384Z

Short URL for this post: http://wp.me/p4nxik-1pU
This entry was posted in Web as a Platform and tagged , , , , , . Bookmark the permalink.

3 Responses to ECMAScript 5 – the current JavaScript standard

  1. Pingback: ECMAScript 6 – The future of JavaScript | techscouting through the java news

  2. Pingback: ECMAScript 3, 5 y 6: Pasado, Presente y Futuro de Javascript - pixelovers

  3. Thanks, nice summary.

Leave a Reply