The standard published under the dry title ECMA-262, 5th Edition (hereafter referred to as ES5), is the latest version of the ECMAScript specification. ECMAScript is the standard upon which JavaScript—the single most important language on the web today—is built. Because the language also serves as the basis for Adobe ActionScript (in addition to other flavors), it's fair to say that the ECMAScript standard is central to the present and future of interactivity on the web.
Published in December 2009, ES5 represents an incremental improvement in the language, arrived at through a lengthy, and occasionally contentious, process. Still, whatever friction there might have been in the development of the specification, the end result contains some excellent enhancements to the language. This article outlines the long history of the specification's development, then steps through many of its important new features and concepts.
Not surprisingly, considering the various companies and individual personalities involved in the development of this increasingly important specification, the path to ES5 was a long and varied one. The organization formerly known as the European Computer Manufacturers Association (ECMA)—now simply known by the non-acronym name Ecma—is an international computer and information systems standards organization. The majority of web standards dealt with are housed at the W3C, including the closely related DOM specification. JavaScript/ECMAScript, however, is not. In his epic series of presentations on JavaScript, Yahoo!'s JavaScript architect, Douglas Crockford, offers a colorful explanation for this circumstance.
The time is 1996, and JavaScript is a wildly popular browser innovation from Netscape that Microsoft®, playing catch-up in the web browser space, reverse-engineered and presented as a feature in its Windows® Internet Explorer® browser. Crockford explains:
"Netscape looked at [JScript] with alarm: Oh no, we're going to be embraced and extended, so we need to make a standard out of this. So, they went to W3C and said okay, we've got a language for you to standardize. W3C had been waiting for a long time for an opportunity to tell Netscape to go to hell, so they told Netscape to go to hell.
"Netscape went around to ISO and other places looking for a place where they could buy a standard, and they eventually ended up at the European Computer Manufacturers Association, which is a long way to go for a California software company, but that's where they ended up."
The good news is, even with such a vagabond origin story, the standardization of ECMAScript has served the web development community at large well—even if Netscape itself didn't fare quite as well.
Before ES5, the last major version of the specification was the third edition, published in December 1999. Work on the edition that was originally meant to be ES4 commenced after the third edition was published. An interim report was published in 2003, which lead to implementation work by Adobe and Microsoft, but progress on the main standard stalled until the fall of 2005, when the Task Group 1 of Ecma Technical Committee 39 (TG1) began meeting regularly.
In hindsight, this was an auspicious time to have restarted the process, as the Asynchronous JavaScript + XML (Ajax)-led renaissance of JavaScript was just beginning in earnest. Jesse James Garrett's seminal article, "Ajax: A New Approach to Web Applications," (see Resources) had been published in February of that year, and the technical design paradigms that you take for granted now were being forged at a furious pace.
Basing their work on ES3 (the report published in 2003) and lessons learned from Adobe and Microsoft's implementations, TG1 moved toward what was to be a radical reworking of the language. It's outside of the scope of this article to go into the details of the proposed specification, but the ambitious goals of the specification lead to controversy in the working group itself.
In 2007, this internal strife—a conflict that touched on the fundamental goals of the specification—was made public. The publicly visible split was between Chris Wilson of Microsoft and Brendan Eich of Mozilla, the original designer of the language. The two men represented opposing viewpoints of what the specification should aim to be.
Eich was the visible representative of the proponents of the radical enhancements of the language then proposed for ES4. Wilson represented those that felt that the changes amounted to "breaking the web," because they represented too dramatic a change from the existing specification. ES4 at that time wouldn't have been backwards compatible—a valid concern echoed in the design decisions made in the What-WG's work on the HTML5 specification.
This split effectively broke the standards group into two pieces: ES4 dissenters (led by Microsoft and Yahoo!) broke off and began working on ECMAScript 3.1, a specification designed to provide incremental improvement and bug fixes. Meanwhile, Eich and other ES4 proponents were still working on the ES4 specification. Recognizing the negative effects of the split and presumably the growing importance of ECMAScript to the future of the web, the standards group got together in July 2008 (in what's been dubbed the "Oslo Meeting") to patch over their differences. Thankfully for us, TG1 emerged from the meeting with a new accord.
The plan, announced by Eich on the respective group's mailing lists, was to focus immediate effort on the 3.1 specification, and then move on to a scaled-back (at least compared to ES4), but still ambitious, reworking of the language called ES-harmony. That 3.1 branch eventually became ES5.
Now that you have a history of the specification, let's take a look at what all that hard work and occasional strife have produced.
New features and concepts of ES5
Several areas have received attention in this latest edition of the standard. The edition contains two major areas of importance and a few smaller, but still useful, changes and additions. I've provided code samples based on support for the new ES5 features. To try out the majority of these samples yourself, you must be running Internet Explorer version 9, Mozilla Firefox version 4, or Google Chrome version 6 or later. You'll also need a console open.
Note: As of this writing, Firefox 4 is the only browser that supports strict mode. For more up-to-date compatibility information, check out the ES5 Compatibility Table (see Resources for a link).
One of the more interesting pieces in the new specification is the introduction of strict mode, an opt-in mechanism that allows developers to use a restricted, but cleaner, subset of the JavaScript language. To invoke the spirit of Doug Crockford, strict mode is designed to fix or limit some of the language's most egregious "bad parts."
Strict mode can be implemented at either the script or function level. This is nice, because it allows module and library authors to choose to write strict code without affecting the rest of the environment. The one thing to keep in mind is that concatenating strict and non-strict scripts for performance reasons can have unintended consequences. See Amazon's bug in the Resources section for an example.
You invoke strict mode at the script level by including the statement
use strict before any other statements in a file.
Listing 1 provides an example.
Listing 1. Invoking strict mode at the script level
"use strict";
var myNamespace = {
myMethod : function(){
//strict code
}
}
|
At the function level, the mode is similarly invoked by including the statement
use strict inside the function body before any other
statement, as shown in Listing 2.
Listing 2. Invoking strict mode at the function level
function getStrict(){
"use strict";
//strict code
}
|
It's interesting to note that the syntax used to invoke strict mode is just a string expression statement, which means that by itself it won't do any harm to include it in your code right now. Browsers that understand it will turn on the subset. Those that don't will read it as an expression statement, ignore it, and then move on to the next line in the code. Of course, there are other concerns with invoking strict mode when only a minority of browsers support it, but the Use Strict Directive itself isn't one of them.
The following sections outline the effect of strict mode on your code. Although it's not an exhaustive examination of every aspect of strict mode, it touches on the major themes of the new mode. The best way to understand strict mode is to work with these examples in a browser that offers support.
For the boldest, you can drop the directive into the head of one of your existing scripts and see how many errors pile up (or not, if you're already careful enough to avoid these pitfalls).
Noisy errors and the death of accidental globals
One section that I'm particularly fond of in strict mode looks like the nitpicky
parts of a code review. Strict mode turns several common negative coding
patterns that would normally be ignored or fail silently in standard script into
actual errors. The most common of these is the accidental creation of a global
variable by assigning a value to an undeclared variable without the use of the
var statement. In standard code, this is merely bad
practice. In strict mode, it throws a reference error, as shown in
Listing 3.
Listing 3. No accidental globals
function nopullution(){
"use strict";
myAccidentalGlobal = "polluting the global namespace is for losers";
}
nopullution();
>>>Error: assignment to undeclared variable myAccidentalGlobal
|
Accidental globals are also prevented by a change in the way the
this keyword is bound in certain situations. For
example, if a constructor function is called directly instead of with the new
prefix, this will be bound to the global object.
Strict mode binds this, in those situations, to
undefined, preventing unexpected pollution of the
global namespace.
In addition, actions that would simply fail silently, like deleting an undeletable property or repeating argument or property names, now throw errors. Examples of these are given in Listing 4.
Listing 4. Noisy errors
"use strict"
delete Array.prototype;
>>>Error: property "use strict";Array.prototype is non-configurable and
can't be deleted
"use strict"
var myObj ={
dupe: 1,
dupe :2
}
>>>Error: property name dupe appears more than once in object literal
|
Strict mode also enforces static binding of variable names by doing away with the
language features that relied on dynamic binding. It does this by prohibiting
the use of the with statement by limiting the ability
of eval to create variables in the calling context.
In strict mode, eval is executed in a sandbox that
is destroyed after the eval ends. One benefit of this
is that JavaScript minification tools see compression improvements because they
can optimize around static bindings.
The second area of interest is a set of much-needed enhancements to the core
Object. Object has been
strengthened with several new features that add powerful, necessary tricks to the
ECMAScript inheritance toolbox.
You use the Object.create method to create a new
object with a specified prototype object and an additional properties object.
This is a powerful new interface to object creation, inheritance, and reuse.
With create(), inheritance can be set and an object
enhanced—all in one cleanly defined interface. With the new features
presented by Object properties available, JavaScript
inheritance has become a much more straightforward endeavour.
Listing 5 offers a simple example.
Listing 5. Using Object.create()
//create a simple, traditional object that has some properties
var marvelProto = {
publisher : "Marvel Comics",
founded : "1939",
founder : "Martin Goodman",
headquarters : "417 5th Avenue, New York, NY, U.S."
}
//create a new object that inherits properties from the simple object
//create() takes two arguments. the object that will serve
//as the new object's prototype and an optional set of
//new properties to populate the new object
var FantasticFour = Object.create(
marvelProto,
{
title : {
value : "Fantastic Four",
},
year : {
value : "1961",
}
}
);
console.log(
FantasticFour.title
+" was first published by "+
FantasticFour.publisher
+" in "+
FantasticFour.year
);
|
Enhancing the power of create() is a set of new
property attributes that allow for much finer control of inheritance. You saw
one in the previous example: the explicitly labeled value.
Three other Boolean flags greatly enhance the flexibility and control you will
have over your Objects:
- You can change the value of writable properties.
enumerableindicates whether the property is visible tofor...inloops and in the newObject.keys()method.- You can delete configurable properties and alter their attributes.
The previous example can be improved with the new property attributes to lock down several attributes that shouldn't change after they are defined. This new version is visible in Listing 6.
Listing 6. Leveraging property attributes to define objects
var marvelProto = Object.create(
//pass in the default object as a template
{},
{
//and then create more finely defined properties
publisher : {
value : "Marvel Comics",
//yes, we want it exposed
enumerable: true,
//Theoretically, the value might change
writable: true,
//but it can't be deleted/edited
configurable: false
},
founded : {
value : "1939",
enumerable: true,
//this won't change, so we stop it from being overwritten
writable: false,
configurable: false
},
founder : {
value : "Martin Goodman",
enumerable: true,
writable: false,
configurable: false
},
headquarters : {
value : "417 5th Avenue, New York, NY, U.S.",
enumerable: true,
//we might need to edit at some point
writable: true,
configurable: false
}
}
);
var FantasticFour = Object.create(
marvelProto,
{
title : {
value : "Fantastic Four",
enumerable: true,
writable: false,
configurable: false
},
year : {
value : "1961",
enumerable: true,
writable: false,
configurable: false
}
}
);
console.log(
FantasticFour.title
+" was first published by "+
FantasticFour.publisher
+" in "+
FantasticFour.year
);
|
Continuing the trend of being able to fine-tune and control Objects,
ES5 has created three new methods that allow differing levels of "lockdown" to be
applied to an object. These powerful, much-needed tools significantly increase the
predictability of ECMAScript programs.
Note: Strict mode is used throughout these examples to force errors to be thrown when trying to perform actions prevented by the lockdown methods.
Object.preventExtensions() and Object.isExtensible()
The first of these lockdown methods is Object.preventExtensions(),
which stops any new named properties from being added to an object.
Object.isExtensible() tests whether named properties
can be added to an object. These methods are illustrated in
Listing 7.
Listing 7. Using Object.preventExtensions() and Object.isExtensible()
"use strict"
var marvelProto = Object.create(
//pass in the default object as a template
{},
{
publisher : {
value : "Marvel Comics",
enumerable: true,
writable: false,
configurable: false
}
/*...OTHER PROPERTIES*/
}
);
//Let's see if we can add some more info to the object
if (Object.isExtensible(marvelProto)){
//true
marvelProto.flagshipCharater = "Spider-Man";
};
//Stop extensions
Object.preventExtensions(marvelProto);
//Adding an Editor in Chief field throws an error
marvelProto.editorInChief = "Axel Alonso";
>>>TypeError: Can't add property editorInChief, object is not extensible
|
Object.seal() and Object.isSealed()
Object.seal first calls Object.preventExtensions()
to prevent new properties from being added, and then sets the
configurable flag of all object properties to false.
This lets you lock down an object for all but its values, making it predictable
to use as a data store. Looping through the values of a sealed data object is
now a much more predictable task, especially when paired with the
enumerable flag. Object.isSealed()
tests whether an object is configurable. Listing 8 shows an
example of these methods in action.
Listing 8. Using Object.seal() and Object.isSealed()
"use strict"
var marvelProto = Object.create(
//pass in the default object as a template
{},
{
publisher : {
value : "Marvel Comics",
enumerable: true,
writable: false,
configurable: false
},
/*...OTHER PROPERTIES*/
//optional properties
flagshipCharacter : {
value : "Spider-Man",
enumerable: true,
writable: false,
configurable: true
},
editorInChief : {
value : "Axel Alonso",
enumerable: true,
writable: false,
configurable: true
}
}
);
//Can we delete configurable properties?
if (!Object.isSealed(marvelProto)){
//we can
delete marvelProto.flagshipCharacter;
};
//Seal the object
Object.seal(marvelProto);
//deleting the Editor in Chief field throws an error
delete marvelProto.editorInChief;
>>>Error: property "use strict";marvelProto.editorInChief is
non-configurable and can't be deleted
|
Object.freeze() and Object.isFrozen()
Object.freeze calls Object.seal()
to stop configuration of an object, and then sets the writeable
flag of all object properties to false, providing a perfectly static object. In
environments where multiple sources are interacting with data, the ability to
completely freeze objects creates a level of predictability and safety that hasn't
really been available before.
Object.isFrozen() tests whether the object is frozen.
Listing 9 provides an example of this method in action.
Listing 9. Using Object.freeze() and Object.isFrozen()
"use strict"
var marvelProto = Object.create(
//pass in the default object as a template
{},
{
publisher : {
value : "Marvel Comics",
enumerable: true,
writable: false,
configurable: false
},
//optional properties
flagshipCharacter : {
value : "Spider-Man",
enumerable: true,
writable: false,
configurable: true
}
}
);
//Can we write writeable properties?
if (!Object.isFrozen(marvelProto)){
//we can
marvelProto.flagshipCharacter = "Iron Man";
};
//Seal the object
Object.freeze(marvelProto);
//Changing the Flagship Character throws an error
marvelProto.flagshipCharacter = "Wolverine";
>>>Error: "use strict";marvelProto.flagshipCharacter is read-only
|
The new method Object.getPrototypeOf() returns the
prototype of an object. Its value is
equivalent to the nonstandard Object.__proto__
property.
Object.keys() and Object.getOwnPropertyNames()
The Object.keys() method returns an array of strings
representing the names of an object's own enumerable properties, meaning
properties defined directly on the object being surveyed whose
enumerable flag is set to true.
Object.getOwnPropertyNames() is similar, but also
includes properties that have the enumerable flag
set to false. Both of these methods are illustrated in Listing 10.
Listing 10. Using Object.keys() and Object.getOwnPropertyNames()
var USComicPublishers = {
countryOfOrigin : {
value : "USA",
enumerable: true,
writable: false,
configurable: false
},
medium : {
value : "comic books",
enumerable: true,
writable: false,
configurable: false
}
}
var marvelProto = Object.create(
//inherits properties from another Object
USComicPublishers,
{
publisher : {
value : "Marvel Comics",
enumerable: true,
writable: false,
configurable: false
},
founded : {
value : "1939",
enumerable: true,
writable: false,
configurable: false
},
founder : {
value : "Martin Goodman",
enumerable: true,
writable: false,
configurable: false
},
headquarters : {
value : "417 5th Avenue, New York, NY, U.S.",
enumerable: true,
writable: true,
configurable: false
},
launchComic : {
value : function(){
/*fancy code to create a new comic series
this isn't data we want to expose when we inspect
inherited objects */
return true;
},
enumerable: false,
writable: true,
configurable: false
}
}
);
//inherits medium from parent, as expected
console.log(marvelProto.medium.value);
>>>comic books
//Our function is available
console.log(marvelProto.launchComic());
>>>true
//BUT... keys returns ONLY properties on object itself
//inherited properties are ignored
//launchComic (enumerable:false) is also skipped
console.log(Object.keys(marvelProto));
>>>["publisher", "founded", "founder", "headquarters"]
//getOwnPropertyNames also operates only on
//properties of the object itself, but it
//also includes properties that have the
//enumerable flag set to false
console.log(Object.getOwnPropertyNames(marvelProto);
>>>["launchComic", "founder", "founded", "headquarters", "publisher"]
|
Accessors (getters and setters)
Get and set bind an
object property to a function that will be called when there's an attempt to
access or write a property's value. Get takes zero
arguments; set takes one (the value to set.) Both
of these elements are illustrated in Listing 11.
Listing 11. ECMAScript getters and setters
var marvelProto = Object.create(
//pass in the default object as a template
{},
{
publisher : {
value : "Marvel Comics",
enumerable: true,
writable: false,
configurable: false
},
/*OTHER PROPERTIES*/
}
);
var FantasticFour = Object.create(
marvelProto,
{
title : {
value : "Fantastic Four",
},
year : {
value : "1961",
}
}
);
//Use Object.defineProperty to set the getters and setters
//Alternatively, this could be set in the Object.create above
Object.defineProperty(FantasticFour, "bestIssue", {
get: function () { return fave; },
set: function (num) {
fave = "The best single issue of Fantastic Four is issue #" + num;
}
}
);
FantasticFour.bestIssue = 51;
console.log(FantasticFour.bestIssue);
>>>The best single issue of Fantastic Four is #51
|
Another area that received a lot of attention in the new specification is the array.
The changes here aren't quite as fundamental or as powerful as the enhancements
to Object, but there are many new methods worth noting.
The Array.forEach function takes a single argument:
a function to be executed once for every element in an array. The function
executed is passed three arguments: the specific element being accessed, the
index of the element, and the array itself. Listing 12
shows a simple use of this convenience method.
Note: This method is significantly slower than an equivalent
for loop because of the overhead of running a
separate function every time. For every step, a new execution context is created
and destroyed, and another level is added to the scope chain. Those add up.
Listing 12. Array.forEach() example
var arr = [8, 10, 13, 10, 8, 1, 5];
function logger(element, index, array) {
console.log("The value of the element at index " + index + " is " + element);
}
arr.forEach(logger);
>>>The value of the element at index 0 is 8
>>>The value of the element at index 1 is 10
>>>The value of the element at index 2 is 13
>>>The value of the element at index 3 is 10
>>>The value of the element at index 4 is 8
>>>The value of the element at index 5 is 1
>>>The value of the element at index 6 is 5
|
Array.map returns a new array produced by calling
a single function argument on every element in this array. The provided
function receives the element in the array as a single argument. A simple
example is provided in Listing 13.
Listing 13. Array.map() example
var arr = [8, 10, 13, 10, 8, 1, 5];
function square(num){
return num * num;
}
console.log(arr.map(square));
>>>[64, 100, 169, 100, 64, 1, 25]
|
Array.reduce() and Array.reduceRight()
Reduce and reduceRight
both execute a provided function against two elements of an array, working
through the entire array to produce a single value. Array.reduce
does this from left to right; Array.reduceRight()
processes the array from right to left. Examples of both, including one that shows
the importance of order, are shown in Listing 14.
Listing 14. Using Array.reduce() and Array.reduceRight()
var arr = [8, 10, 13, 10, 8, 1, 5];
console.log(arr.reduce(function(a, b){ return a + b; }));
>>>55
console.log(arr.reduce(function(a, b){ return a +" "+ b; }));
>>>8 10 13 10 8 1 5
console.log(arr.reduceRight(function(a, b){ return a + b; }));
>>>55
console.log(arr.reduceRight(function(a, b){ return a +" "+ b; }));
>>>5 1 8 10 13 10 8
|
The Array.filter() function returns a new array
containing all elements that pass a test implemented by the single function
argument. An example using a simple even/odd test is provided in
Listing 15.
Listing 15. Using Array.filter()
var arr = [8, 10, 13, 10, 8, 1, 5];
function odd(element, index, array) {
return (element%2);
}
console.log(arr.filter(odd));
>>>[13, 1, 5]
|
Array.every() and Array.some()
Both Array.every() and Array.some()
test elements in an array against a single function argument.
Array.every() returns true if all elements in the
array pass the test implemented by the provided function.
Array.some() returns true if any single element in
the array passes the test implemented by the provided function. Examples of
both, using a simple even/odd test, are provided in Listing 16.
Listing 16. Using Array.every() and Array.some()
var arr = [8, 10, 13, 10, 8, 1, 5];
function odd(element, index, array) {
return (element%2);
}
console.log(arr.every(odd));
>>>false
console.log([1,3,5].every(odd))
>>>true
console.log(arr.some(odd));
>>>true
console.log([2,4,6].some(odd))
>>>false
|
Array.indexOf() and Array.lastIndexOf()
The Array.indexOf() and Array.lastIndexOf()
functions both return an index at which a given element can be found in the
array, or -1 if it's not present. Array.indexOf
begins its search at the first element of the array or an optional position argument,
and then searches forward to the end of the array, looking for a match.
Array.lastIndexOf begins its search at the last element
of the array or an optional position argument, and then searches backward to the
beginning of the array, looking for a match. Simple examples of each are shown in
Listing 17.
Listing 17. Using Array.indexOf() and Array.lastIndexOf()
var arr = [8, 10, 13, 10, 8, 1, 5];
console.log("lastIndexOF is " + arr.lastIndexOf(10));
>>>lastIndexOF is 3
console.log("indexOF is " + arr.indexOf(10));
>>>indexOF is 1
|
JSON is a popular data-interchange format based on a subset of JavaScript syntax.
ES5 standardizes JSON in a manner compatible with the reference json2.js
implementation. It provides two methods: JSON.parse()
and JSON.stringify().
The JSON.parse() method takes a string of JSON text
and, if valid, converts it to an object or array. Listing 18
illustrates a simple use of JSON.parse(), converting
a string back into an object.
Listing 18. Parsing a JSON string with JSON.parse()
var marvel = JSON.parse('{"publisher":"Marvel Comics", /*other properties*/}');
console.log(marvel.founder);
>>>Martin Goodman
|
The JSON.stringiy() method converts an object to
a JSON string. Listing 19 converts the example object
into a string.
Listing 19. Converting an object to a string using JSON.stringify()
var marvelProto = Object.create(
{},
{
publisher : {
value : "Marvel Comics",
enumerable: true,
writable: false,
configurable: false
}
/*OTHER PROPERTIES*/
}
);
console.log(JSON.stringify(marvelProto));
{"publisher":"Marvel Comics","founded":"1939","founder":"Martin Goodman"}
|
Other interesting new features
A couple of other new features are worth pointing out before the article wraps up.
The Date.now() method is a handy new method for
getting the current time. This method replaces the common
(new Date()).getTime() pattern. Listing 20
shows an example of Date.now() that tests the
difference between the 500 millisecond argument sent to setTimeout
and the actual clock time between executions of the function.
Listing 20. Using Date.now()
var datePrev = Date.now(),
dateNow,
count=0;
function later(){
if (count < 5 ){
dateNow = Date.now();
console.log(datePrev - dateNow);
datePrev=dateNow;
setTimeout(later,500);
count++;
}
}
later();
>>>0
>>>-487
>>>-500
>>>-512
>>>-500
|
At its simplest, Function.prototype.bind, a popular
innovation from Prototype.js, defines a function to be executed at some later
date with a specified this value. In addition, arguments can be specified and
bound to the function, allowing for customization of bound functions. A basic
example of this powerful feature can be see in Listing 21.
Listing 21. A simplified Function.prototype.bind() example
//global values;
var favoriteIssue = 27,
title = "Detective Comics";
var myFavoriteComic = {
returnFavorite: function() {
if (arguments.length && arguments[0].newComic) {
this.favoriteIssue =arguments[0].newComic.favoriteIssue
this.title =arguments[0].newComic.title
};
//what's this?
console.log("this is "+this);
//display the values
console.log("My favorite issue of "+ this.title +" is #" + this.favoriteIssue);
},
favoriteIssue: 168,
title : "Daredevil"
};
//this is myFavoriteComic
//values are internal to the module
myFavoriteComic.returnFavorite();
>>>this is [object Object]
>>>My favorite issue of Daredevil is #168
//now we let this slip to the global object
var makeGlobal = myFavoriteComic.returnFavorite;
makeGlobal();
>>>this is [object Window]
>>>My favorite issue of Detective Comics is #27
//use bind to bind it to the correct this value
var boundToModule = makeGlobal.bind(myFavoriteComic);
boundToModule();
>>>this is [object Object]
>>>My favorite issue of Daredevil is #168
//pass in options to change the module values
var updatedFavoriteIssue = makeGlobal.bind(
myFavoriteComic,
{
newComic :
{
favoriteIssue:51,
title:"Fantastic Four"
}
}
);
updatedFavoriteIssue()
>>>this is [object Object]
>>>My favorite issue of Fantastic Four is #51
|
Finishing with a method inspired by the work of a library is a fitting way to wrap up this article, for it's in the hands of library authors and other core JavaScript developers that the real power of the new features and functions in the specification will be uncovered. As more and more browsers come on board with ES5 support, and more developers dig in and start working with the latest version of the specification, you'll really start to get a feel for what's possible with these new tools. Considering the work browser vendors and developers have done on top of a 10-year-old specification, this modern revision looks like it will be the foundation of an exciting few years on the web.
Learn
-
Read the ECMA-262
ECMAScript Language Specification, 5th edition (December 2009).
-
Check out the video from Douglas Crockford's Crockford on JavaScript,
Chapter 2:
And Then There Was JavaScript.
-
For a historical perspective on the ES4 controversy, read Chris Wilson's dissenting post
on the proposed ES4 specification,
What
I think about ES4.
-
Responding to Chris Wilson, Brendan Eich's wrote
Open
letter to Chris Wilson.
-
Check out the ECMAScript 5
compatibility table.
-
Read Jesse James Garrett's article,
"Ajax: A
New Approach to Web Applications."
-
The Web development zone
specializes in articles covering various web-based solutions.
-
Stay current with developerWorks'
technical
events and webcasts.
-
developerWorks on-demand
demos: Watch demos ranging from product installation and setup for beginners
to advanced functionality for experienced developers.
Get products and technologies
-
Learn more about ECMAScript
Harmony.
-
Download IBM product evaluation
versions or explore
the online trials in the IBM SOA Sandbox and get your hands on application
development tools and middleware products from DB2®, Lotus®, Rational®,
Tivoli®, and WebSphere®.
Discuss
- Create your developerWorks profile today and set up a watchlist on JavaScript.
Get connected and stay connected with developerWorks community.
- Find other developerWorks members interested in web development.
- Share what you know: Join one of our developerWorks groups focused on web topics.
- Roland Barcia talks about Web 2.0 and middleware in his blog.
- Follow developerWorks' members' shared bookmarks on web topics.
- Get answers quickly: Visit the Web 2.0 Apps forum.
- Get answers quickly: Visit the Ajax forum.

Rob Larsen has more than 11 years of experience building and designing websites and web applications. Currently, he's an interface architect at Isobar, working with HTML5, CSS3, and other emerging technologies for some of the world's largest brands. Rob writes about the web and web technologies at his blog, HTML + CSS + JavaScript, and you can reach him at rob@htmlcssjavascript.com.




