What’s new in JavaScript 1.8.5

What’s new in JavaScript 1.8.5

Tutorial Details
  • Topic: JavaScript
  • Difficulty: Easy
  • Estimated completion time: 20 minutes

It’s a great time for JavaScript. Not only is it becoming a much more respected language, but it’s also growing in leaps and bounds – both in popularity and features. As more browsers begin to implement the features of the ECMAScript 5th edition standard, JavaScript becomes an even more powerful platform for you to develop on. In this tutorial, we’ll talk about the new methods that are available to you.


What is ECMAScript 5?

ECMAScript is the official name of what we all call JavaScript. That doesn’t mean we’re wrong; it’s just that the name “JavaScript” is a trademark of Oracle; so Ecma International (originally the European Computer Manufacturers Association—hence ECMA) uses the term “ECMAScript” to refer to the standard of JavaScript. The latest version of this standard is the 5th edition, and it was approved just over a year ago (on December 3, 2009). It encompasses a huge range of great additions, and several of those are starting to show up in browsers. The implementations of ECMAScript 5 is called JavaScript 1.8.5.

In this tutorial, we’re going to be looking at the JavaScript 1.8.5 functions that are available to us in the Firefox 4 betas. You’ll be happy to discover that most of the latest versions of other browsers have these, too . . . except for one. This time, it’s Opera, as IE9 has included many of these.


Function 1: Object.create

This method is a very important one; it really cleans up prototypal inheritance. Previously (in ECMAScript 3rd edition), to create an object and set its prototype, you’d do something like this:

function Cat(name) {
    this.name   = name;
    this.paws   = 4;
    this.hungry = false;
    this.eaten  = [];
}
Cat.prototype = {
    constructor : Cat, 
    play        : function () { this.hungry = true; return "playing!"; },
    feed        : function (food) { this.eaten.push(food); this.hungry = false; },
    speak       : function () { return "Meow" }
};

Am I the only one who thinks it looks weird to have the prototype outside the constructor function? And inheriting gets even messier. With Object.create, things get a lot easier. The above could be coded like this:

var dog = {
    name   : "dog",
    paws   : 4,
    hungry : false,
    eaten  : null,
    play        : function () { this.hungry = true; return "playing!"; },
    feed        : function (food) { if (!this.eaten) { this.eaten = []; } this.eaten.push(food); this.hungry = false; },
    speak       : function () { return "Woof!" }
};

var my_dog = Object.create(dog);

What’s going on here is this: I’m calling object.create, passing it an object to use as the prototype of the new object that Object.create is returning. When using Object.create, I don’t have to worry about defining the prototype separately. In fact, I have a lot more flexibility to decide how to go about creating and inheriting objects. For example, I can’t put the eaten array on the prototype, because an array is a reference value, so every object created from dog will share that array. I’ve decided to check for it before using it here, but if I wanted to wrap Object.create(dog) in a make_dog function, I could assign it there just as easily.

That’s what’s great about Object.create; you can choose how to do it.

There’s a second parameter that Object.create takes; it’s a properties descriptor object. It’s a bit complicated, but it’s also a part of the next function we’ll look at, so let’s check that out.


Function 2: Object.defineProperty

If you’ve got an object that you want to define a property on, you’ll probably do it this way:

my_dog.age = 2;

This still works fine in ES5, but if you want some more fine-grained control, you can have it with Object.defineProperty. The first parameter is the object you’re assigning the property on. The second parameter is the name of the property, as a string. The final property is the descriptor object. Here’s how that works. It’s (obviously) an object and it can have a combination of the following properties, all of which describe the property we’re adding:

  • value: use this to set the value of a property. Defaults to undefined.
  • writable: use this boolean to define whether this is a read-only variable. If it’s writable, it’s true. Defaults to false.
  • configurable: use this boolean to define whether the type (value vs. method) of this property can be changed, or whether the property can be deleted. If it’s configurable, it’s true. Defaults to false.
  • enumerable: use this boolean to define whether this property is included when the properties of the object are enumerated (a for-in loop or the keys method). Defaults to false.
  • get: use this to define a custom getter method. Defaults to undefined.
  • set: use this to define a custom setter method. Defaults to undefined.

Notice that the defaults for the boolean options above are the reverse of the old obj.prop = val standards. Also, know that you can’t define value or writable when get or set are defined, and vice versa.

So, how would you use this? Try this:

// assume my_dog from above

Object.defineProperty(my_dog, "age", { 
    set : function (age) { this.human_years = age * 7; },
    get : function () { return this.human_years / 7; },
    enumerable : true
});

my_dog.age = 2;
my_dog.human_years; // 14

Apart from the fact that dog years aren’t really 7 human years, you should notice that we didn’t set value or writable here, because we’re using get and set. These functions aren’t ever accessed directly. They are “magically” run behind the scenes when you assign or request a property. In this example, I’m using these functions to keep age and human_years in “sync.” If you don’t want the “other” value accessible, you could use a anonymous, self-invoking function to hide it with closure:

Object.defineProperty(my_dog, "age", (function () {
    var human_years;

    return {
        set : function (age) { human_years = age * 7; },
        get : function () { return human_years / 7; },
        enumerable : true
    };

}()));

Of course, there’s nothing to stop you from doing something stupid inside get or set, so use it wisely.

You can use a form of the property descriptor object to add properties to objects with Object.create. Do it as follows:

var your_dog = Object.create(dog, {
    age : {
        get : function () { /* . . . */ },
        set : function () { /* . . . */ },
        enumerable: true
    },
    gender : {
        value : "female" 
    }
});

Just use the property name as a property of the descriptor object; then, set the attributes via an object in the value.


Function 3: Object.defineProperties

If you want to define several properties at once, you can use a property descriptors object just as with Object.create to define them, using Object.defineProperties.

Object.defineProperties(my_dog, {
    age : {
        get : function () { /* . . . */ },
        set : function () { /* . . . */ },
        enumerable: true
    },
    gender : {
        value : "female" 
    }
});

You’ll want to note—for the rare case when you’re not using an object literal as the second parameter—that only the enumerable properties of the properties object will be used.


Function 4: Object.getOwnPropertyDescriptor

If you ever want to know the specifics of a property, you can use this function, Object.getOwnPropertyDescriptor. Take note of the “Own”; this only works with properties on the object itself, not up its prototype chain.

var person = { name : "Joe" };

Object.getOwnPropertyDescriptor(person, "name"); // { configurable : true, enumerable : true, value : "Joe", writable : true }

As you can see, this works with properties set in both the old and new way. Object.getOwnPropertyDescriptor takes two parameters: the object and the property name as a string.


Function 5: Object.keys

Ever wanted to get all the keys of an object? Now, you can do so easily with Object.keys. Pass this function an object, and it will return an array of all the enumerable properties of that object. You can also pass it an array, and you’ll get back an array of the indices.

var horse = { name : "Ed", age : 4, job : "jumping", owner : "Jim" };

var horse_keys = Object.keys(horse); // ["name", "age", "job", "owner"];

Function 6: Object.getOwnPropertyNames

This one is just like Object.keys, except that it includes all the properties—even the ones that aren’t enumerable. By the longer function name, you can tell they discourage the use of it. Usually, you’ll want keys instead.


Function 7: Object.preventExtensions / Object.isExtensible

If you’ve ever wanted to create a function that doesn’t accept new parameters, you can do so now. Run your object through Object.preventExtensions, and it will decline all attempts to add new parameters. This function goes hand in hand with Object.isExtensible, which returns true if you can extend the object and false if you can’t.

    var product = { name : "Foobar", rating : 3.5 };

    Object.isExtensible(product); // true

    Object.preventExtentions(product);

    Object.isExtensible(product); // false

    product.price = "$10.00"; // doesn't work
    
    product.price; // undefined

You should note that all the properties on the object at the time you run Object.preventExtensions can still be changed or deleted (assuming their attributes allow that).


Function 8: Object.seal / Object.isSealed

Sealing an object is one step up from preventing extensions. A sealed object won’t let you add or delete properties, or change properties from a value (like a string) to an accessor (a method) or vice versa. You’ll still be able to read and write properties, of course. You can find out if an object is sealed by using Object.isSealed.

var pet = { name : "Browser", type : "dog" };

Object.seal(pet);

pet.name = "Oreo";

pet.age = 2; // doesn't work

pet.type = function () { /**/ }; // doesn't work

delete pet.name; // doesn't work

Function 9: Object.freeze / Object.isFrozen

Freezing it yet another step further. A frozen object can’t be changed in any way; it’s read-only. You can verify the frozenness of an object with, you guessed it, Object.isFrozen.

var obj = { greeting : "Hi!" };

Object.freeze(obj);

Object.isFrozen(obj); // true

Function 10: Array.isArray

You’d think that it wouldn’t be too hard to determine that a given variable is an array. After all, everything else works fine with the typeof operator. However, JavaScript arrays are of inconsistent ilk. They’re actually closer array-like objects (even though we usually use that term to refer to things like arguments and NodeLists). This function gives you a way to be 100% sure that what you’re working with is an array. Pass it a variable, and it returns the boolean.

var names = ["Collis", "Cyan"];

Array.isArray(names); // true

For more on why we need this function, check out the docs, linked to below.

  • MDN Documentation
  • Browser Support
    • Firefox 4
    • Internet Explorer 9
    • Safari 5
    • Chrome 5+
    • Opera 10.5+

Function 11: Date.prototype.toJSON

This isn’t too big, but if you ever want to store dates in JSON, you might find this useful. Date objects now have a toJSON function that will convert the date to a JSON string date.

new Date().toJSON(); // "2010-12-06T16:25:40.040Z"

Function 12: Function.prototype.bind

You’re probably familiar with using call and apply to reassign the value of this in a function.

var arr1 = ["1", "2", "3"],
    arr2 = ["4", "5", "6"];

Array.prototype.push.apply(arr1, arr2);

These methods allow you to change the value of this within a function. If you want to do something like this often, Function.prototype.bind returns a new function with this bound to whatever you pass in, so you can save it to a variable.

var tooltip = { text: "Click here to . . . " },
    overlay = { text: "Please enter the number of attendees" };

function show_text () {
    // really, do something more useful here
    console.log(this.text);
}

tooltip.show = show_text.bind(tooltip);
tooltip.show();

overlay.show = show_text.bind(overlay);

overlay.show();

Of course, this might not be the most practical example, but it gives you the idea!


But Wait, There’s More …

Those are the ECMAScript 5th Edition (or JavaScript 1.8.5) functions that have been added to the Firefox 4 betas. There are a few other changes to JavaScript that they are implementing as well, which you can check out in the release notes.

However, there are a bunch of ECMAScipt 5 functions that were already supported in Firefox 3, and several other browsers. Have you played with any of these?

Note: these are linked to their MDN Documentation.

If you want to see which browsers and versions support these functions, you can check out this compatibility table, made by Juriy Zaytsev (Kangax). The nice thing about most of these functions is that if a browser doesn’t support it, you can usually add support, with something like this:

if (typeof Object.create !== 'function') {
    Object.create = function (o) {
        function F() {}
        F.prototype = o;
        return new F();
    };
}
// Courtesy of Douglas Crockford: http://javascript.crockford.com/prototypal.html

What ECMAScript 5 Features are you Using?

The slew of new functions we’ve looked at here is really only a small part of the goodness added to the ECMAScript standard in the 5th edition. Are there any other features you’re specifically looking forward to using, or maybe even using right now? Let’s here it in the comments!

Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • http://www.sz-media.org Sz-Media

    i hate javascript and i love jquery ^^

    • goyote8

      what a dbag, jquery is javascript.

    • http://milesj.me Miles Johnson

      This is one of the most ludicrous posts I have seen on this site. Sigh.

      jQuery does *not* make you a good frontend developer.

      • http://tim.theenchanter.com/ Tim Harper

        I’m actually going to agree with him. Overall, I have a love/hate relationship with Javascript. I love jQuery, it’s a very well-written DOM manipulation framework. I realize jQuery is built with Javascript. Javascript is maturing, and many of the issues are being fixed thanks to the evolving standard!

        Javascript’s saving grace includes prototypal inheritance, first-class functions, POSIX regular expressions, and closures (not in that order). These are REALLY good. It’s ugly parts are object equivalents, inconsistent, odd core library functions…

        * Date.new(year, month – 1, day, …)
        * (5.05).toFixed(1) returns “5.0″, (5.0501).toFixed(1) returns “5.1″…
        * Objects are confined to have string indexes (other primitives not allowed, like integers)

        Equivalence

        > a = new Date; b = new Date(a)
        > a == b
        false
        > a.toString() == b.toString()
        true

        > 1==true
        true

        > “1″ == 1
        true

        (although, equivalence is overcome by using the ===, but it’s a bad default)

        No formal type checking system, etc.

        Much of it can be fixed, and maybe someday a breaking change will be introduced to the javascript language which will really address this stuff.

        But right now… there’s some messed up stuff that makes me sort of love it and hate it at the same time.

    • M.R.

      Are you serious with your comment??? If you are, you’ll be hard to beat as far as being clueless.

      • foljs

        Actually what he says makes a lot of sense.

        And its a lot like seasoned js developers feel with libraries like jQuery et al. That jQuery is in itself javascript does not matter.

        The basic thing is that it implements a far more extensive DSL on top of Javascript to work with the dom and events, and in the progress hides several browser inconsistencies.

        His statements is like that said by some C++ people, that like STL but hate most of C++. Sometimes an add-on to a language (a library, a community, a utility like an IDE, etc) it what makes it preferable to others.

  • http://hosting4developers.com Hosting 4 Developers

    It’s important to note that JavaScript 1.8.5 isn’t widely supported yet by browsers, as far as I know.

    Also, ECMAScript and JavaScript aren’t really the same. ECMAScript is the very core of the language we know as JavaScript – i.e., the syntax, the basic objects such as String, etc., but it doesn’t contain those web-related objects that we all use every day (window, location, W3C DOM related stuff, etc.).

    As for objects such as window and location, they’re not really covered by any standard, but they’re a de facto standard.

    • http://andrewburgess.ca Andrew Burgess
      Author

      Right! I noted that the latest version of Opera doesn’t support many of these functions. But for most of the other browsers, it’s only the latest version or so that has support for these. You should definitely not use them blindly without providing some kind of fallback.

      Isn’t it correct to say that JavaScript is the implementation of the ECMAScript standard? Different browsers have different implementations, or engines. After all, you can use JavaScript—and call it JavaScript—on the server or command line, environments that don’t have the DOM, which is a separate standard.

      • Balázs Galambosi

        The most correct would be to say that Javascript is the name of Mozilla’s implementation of ECMAScript. The implementation IE uses is called JScript.

        But historically the ECMAScript standardization process came later, so most people call the whole mess Javascript all together (including the DOM which is just plain wrong).

        And while the implementations of the DOM differ widely (especially IE’s), the ECMAScript language implemented in browsers is surprisingly solid.

        There are exceptions of course: http://kangax.github.com/nfe/

      • Abhijit

        I think it is better to say that Javascript is “an implementation” of ECMAScript. There are other implementations like ActionScript.

      • http://Jonathancutrell.com Jonathan

        It would be *most* correct to say that JavaScript is an implementation of ECMAScript. JavaScript was first introduced in Netscape navigator in 1995, and was copied by IE (nearly indistinguishable differences) with JScript in 1996. It wasn’t until later that both became standardized under ECMA; technically, IE still runs JScript (I think). As it was pointed out, ActionScript is definitely not JavaScript, but it is however ECMAScript.

  • http://twitter.com/xpages2010 Ernest

    What about to include a calendar. The JS Date object is very limited and tie to the host computer to handle time zones.

    • http://stylr.nl Robin

      That’s what HTML5 is doing when you have an input field with the type “date”. You get a native datepicker.

  • http://www.wdonline.com/ Jeremy McPeak

    Object.defineProperty is listed as supported in IE9. While true, IE8 also implements that method.

    • http://andrewburgess.ca Andrew Burgess
      Author

      Ahh, good catch! I think I put IE9 because—according to kangax’s chart and the MSDN docs—Object.defineProperty will only work for DOM objects, and not just regular JS objects, in IE8.

      Thanks for pointing that out! :)

  • http://www.shiftedwork.de/blog Daniel S

    Aaaah the damn browser support… so JS Frameworks like jQuery will benefit from this in ~5 years.

  • http://imperion.pl Paweł P.

    Ulala “This time, it’s Opera“.
    I am wondering why? Best regards!

    • http://andrewburgess.ca Andrew Burgess
      Author

      Same here! Opera’s usually near the top of the pack; I’m guessing it’ll have these in the next few months.

    • Jason
  • http://www.moviemusicgame.com mmgfan

    Sounds like it has a lot of great features. But it’s only supported in the latest version of browsers, not even Firefox 3, so how you expect it being used. Useless for now, right?

    • http://andrewburgess.ca Andrew Burgess
      Author

      It’s definitely not useless now, mainly because you can re-create some of them with plain JavaScript. I gave the example of Object.create, but a few others (included the array methods that are in FF3) can be written “from scratch.” Of course, you won’t be able to do the property customization and object freezing stuff in today’s browsers, but it’s good to be aware of what’s coming :)

  • https://alexay.wordpress.com/ Alex Yorke

    With the added addition of freezing objects, it seems like it’s going ruby-style. Cool.

  • Avinash

    Thanks for bringing up this tutorial ^.^

  • http://www.tixz.dk/ Emil Melgaard

    Most of these features are already implemented today for browsers of lower version through the prototype.js library.

    It’s a greatly overlooked library, much more powerful the jQuery in my opinion, if you’re a programmer. As a designer you probably wont find it very useful, and it’s not as easy to use for making GFX.

    The power of it lies in the ability to write proper javascript and write OOP javascript.

    • Om

      Mootools gives u an even greater deal of a perfectly Object Oriented Structure and Code than prototype
      Not to mention the Heavy and Bulgy ExtJS (Sencha)

  • http://hypergraphs.de Axel Rauschmayer

    The description of function 7 sounds wrong: “If you’ve ever wanted to create a function that doesn’t accept new parameters”. Isn’t it about creating objects to which one cannot add new attributes?

  • http://smokintops.com Matthieu

    Hi,

    once again, nice tutorial Andrewl!

    I’m just wondering how we get the Javascript version that a browser supports. And also do you know what Javascript version frameworks such as jQuery use?

    Thanks

  • http://freedownloadablefullgames.com/ Bryan

    These are some cool new features but sadly it’s not supported by older browsers which a lot of people are still using. I guess I need to wait for some time before I start implementing this.

  • http://forgetdbigwords.com Okeowo Aderemi

    I guess while it’s not Compatible with Most Browser Developers should still pratice with it so that by the time it becomes Norm in all Browsers Our Knowledge of the New EcmaScript will be lot easier,i understand when People say they Hate Javascript it’s not that Fun to Learn but Framworks makes it sane in some ways,i used to use Jquery but wasn’t comfortable enough as i am with the Dojo Toolkit it makes my code easier to read,i guess all Frameworks will update to accomodate for this

  • http://www.wirfs-brock.com/allen Allen Wirfs-Brock

    > The implementations of ECMAScript 5 is called JavaScript 1.8.5.

    This isn’t correct as a general statement. More correct would be: “The Mozilla Firefox implementation of ECMAScript 5 is called JavaScript 1.8.5″.

    Other browsers may use different names or different version numbers to refer to their implementations.

  • http://merrickchristensen.com Merrick Christensen

    Hmm. Looks like JavaScript is starting to catchup to many of the features already implemented by the MooTools team. JavaScript FTW!

  • http://sql-plsql.blogspot.com Sachin

    looks like it has lots of cool new features…..just bookmarked this tutorial to read it in free time..thanks a lot.

  • angelOS

    I like the enumerable ruby style like forEach, map, etc…I’ve worked with prototype since long time ago and still using this basicly for the enumerable library (I hate use for for iterate, it look so static)…now I think I will miss prototype….

  • http://www.ranjanbros.com ranjanbros provides Free Article ,Latest Updates ,Important News,science,technologies,media,politics

    Excellent site. Plenty of helpful information here. I am sending it to a few buddies ans additionally sharing in delicious. And naturally, thank you to your effort!