O'Reilly logo

Supercharged JavaScript Graphics by Raffaele Cecco

Stay ahead with the world's most comprehensive technology and business learning platform.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, tutorials, and more.

Start Free Trial

No credit card required

Chapter 1. Code Reuse and Optimization

JavaScript has an undeservedly dubious reputation. Many people have written about its limitations as an object-oriented programming (OOP) language, even questioning whether JavaScript is an OOP language at all (it is). Despite JavaScript’s apparent syntactic resemblance to class-based OOP languages like C++ and Java, there is no Class statement (or equivalent) in JavaScript, nor any obvious way to implement popular OOP methodologies such as inheritance (code reuse) and encapsulation. JavaScript is also very loosely typed, with no compiler, and hence offers very few errors or warnings when things are likely to go wrong. The language is too forgiving in almost all instances, a trait that gives unsuspecting programmers a huge amount of freedom on one hand, and a mile of rope with which to hang themselves on the other.

Programmers coming from more classic and strictly defined languages can be frustrated by JavaScript’s blissful ignorance of virtually every programming faux pas imaginable: global functions and variables are the default behavior, and missing semicolons are perfectly acceptable (remember the rope mentioned in the previous paragraph?). Of course, any frustration is probably due to a misunderstanding of what JavaScript is and how it works. Writing JavaScript applications is much easier if programmers first accept a couple of foundational truths:

  • JavaScript is not a class-based language.

  • Class-based OOP is not a prerequisite for writing good code.

Some programmers have attempted to mimic the class-based nature of languages like C++ in JavaScript, but this is analogous to pushing a square peg into a round hole: it can be done (sort of), but the end result can feel contrived.

No programming language is perfect, and one could argue that the perceived superiority of certain programming languages (or indeed, the perceived superiority of OOP itself) is a good example of the emperor’s new clothes.[1]In my experience, software written in C++, Java, or PHP generates no fewer bugs or problems than projects created with JavaScript. In fact (cautiously sticking my neck out), I might suggest that due to JavaScript’s flexible and expressive nature, you can develop projects in it more quickly than in other languages.

Luckily, most of JavaScript’s shortcomings can be mitigated, not by forcibly contorting it into the ungainly imitation of another language, but by taking advantage of its inherent flexibility while avoiding the troublesome bits. The class-based nature of other languages can be prone to unwieldy class hierarchies and verbose clumsiness. JavaScript offers other inheritance patterns that are equally useful, but lighter-weight.

If there are many ways to skin a cat, there are probably even more ways to perform inheritance in JavaScript, given its flexible nature. The following code uses prototypal inheritance to create a Pet object and then a Cat object that inherits from it. This kind of inheritance pattern is often found in JavaScript tutorials and might be regarded as a “classic” JavaScript technique:

// Define a Pet object. Pass it a name and number of legs.
var Pet = function (name, legs) {
    this.name = name; // Save the name and legs values.
    this.legs = legs;

// Create a method that shows the Pet's name and number of legs.
Pet.prototype.getDetails = function () {
    return this.name + ' has ' + this.legs + ' legs';

// Define a Cat object, inheriting from Pet.
var Cat = function (name) {
    Pet.call(this, name, 4); // Call the parent object's constructor.

// This line performs the inheritance from Pet.
Cat.prototype = new Pet();

// Augment Cat with an action method.
Cat.prototype.action = function () {
    return 'Catch a bird';

// Create an instance of Cat in petCat.
var petCat = new Cat('Felix');

var details = petCat.getDetails();    // 'Felix has 4 legs'.
var action = petCat.action();         // 'Catch a bird'.
petCat.name = 'Sylvester';            // Change petCat's name.
petCat.legs = 7;                      // Change petCat's number of legs!!!
details = petCat.getDetails();        // 'Sylvester has 7 legs'.

The preceding code works, but it’s not particularly elegant. The use of the new statement makes sense if you’re accustomed to other OOP languages like C++ or Java, but the prototype keyword makes things more verbose, and there is no privacy; notice how petCat has its legs property changed to a bizarre value of 7. This method of inheritance offers no protection from outside interference, a shortcoming that may be significant in more complex projects with several programmers.

Another option is not to use prototype or new at all and instead take advantage of JavaScript’s ability to absorb and augment instances of objects using functional inheritance:

// Define a pet object. Pass it a name and number of legs.
var pet = function (name, legs) {
    // Create an object literal (that). Include a name property for public use
    // and a getDetails() function. Legs will remain private.
    // Any local variables defined here or passed to pet as arguments will remain
    // private, but still be accessible from functions defined below.
    var that = {
        name: name,
        getDetails: function () {
            // Due to JavaScript's scoping rules, the legs variable
            // will be available in here (a closure) despite being
            // inaccessible from outside the pet object.
            return that.name + ' has ' + legs + ' legs';
    return that;

// Define a cat object, inheriting from pet.
var cat = function (name) {
    var that = pet(name, 4); // Inherit from pet.
    // Augment cat with an action method.
    that.action = function () {
        return 'Catch a bird';
    return that;

// Create an instance of cat in petCat2.
var petCat2 = cat('Felix');

details = petCat2.getDetails();   // 'Felix has 4 legs'.
action = petCat2.action();        // 'Catch a bird'.
petCat2.name = 'Sylvester';       // We can change the name.
petCat2.legs = 7;                 // But not the number of legs!
details = petCat2.getDetails();   // 'Sylvester has 4 legs'.

There is no funny prototype business here, and everything is nicely encapsulated. More importantly, the legs variable is private. Our attempt to change a nonexistent public legs property from outside cat simply results in an unused public legs property being created. The real legs value is tucked safely away in the closure created by the getDetails() method of pet. A closure preserves the local variables of a function—in this case, pet()—after the function has finished executing.

In reality, there is no “right” way of performing inheritance with JavaScript. Personally, I find functional inheritance a very natural way for JavaScript to do things. You and your application may prefer other methods. Look up “JavaScript inheritance” in Google for many online resources.


One benefit of using prototypal inheritance is efficient use of memory; an object’s prototype properties and methods are stored only once, regardless of how many times it is inherited from.

Functional inheritance does not have this advantage; each new instance will create duplicate properties and methods. This may be an issue if you are creating many instances (probably thousands) of large objects and are worried about memory consumption. One solution is to store any large properties or methods in an object and pass this as an argument to the constructor functions. All instances can then utilize the one object resource rather than creating their own versions.

Keeping It Fast

The concept of “fast-moving JavaScript graphics” may seem like an oxymoron.

Truth be told, although the combination of JavaScript and a web browser is unlikely to produce the most cutting-edge arcade software (at least for the time being), there is plenty of scope for creating slick, fast-moving, and graphically rich applications, including games. The tools available are certainly not the quickest, but they are free, flexible, and easy to work with.

As an interpreted language, JavaScript does not benefit from the many compile-time optimizations that apply to languages like C++. While modern browsers have improved their JavaScript performance enormously, there is still room to enhance the execution speed of applications. It is up to you, the programmer, to decide which algorithms to use, which code to improve, and how to manipulate the DOM in efficient ways. No robot optimizer can do this for you.

A JavaScript application that only processes the occasional mouse click or makes the odd AJAX call will probably not need optimization unless the code is horrendously bad. The nature of applications covered in this book requires efficient code to give the user a satisfactory experience—moving graphics don’t look good if they are slow and jerky.

The rest of this chapter does not examine the improvement of page load times from the server; rather, it deals with the optimization of running code that executes after the server resources have loaded. More specifically, it covers optimizations that will be useful in JavaScript graphics programming.

With Safari, you learn the way you learn best. Get unlimited access to videos, live online training, learning paths, books, interactive tutorials, and more.

Start Free Trial

No credit card required