25 February, 2010

Asynchronous callbacks in JavaScript

var Queue = (function () {
    "use strict";

    function make() {
        var results = [],
            stack = [],
            queue = [];

        function buildControl(queue) {
            var obj = {
                next: function () {
                    obj.next = function () {};
                    stack.shift();

                    var first = stack[0];
                    if (first) {
                        first(buildControl(queue));
                    } else {
                        queue();
                    }
                }
            };
            return obj;
        }

        var obj = {
            make: make,

            sync: function (func) {
                if (typeof func === "function") {
                    stack.push(func);

                    if (stack.length === 1) {
                        func(buildControl(obj.async()));
                    }
                }
            },

            async: function (func) {
                var index = queue.push(func) - 1;

                return function () {
                    if (index === null) {
                        return;
                    }

                    results[index] = Array.prototype.slice.call(arguments);
                    index = null;

                    for (var i = 0; i < queue.length; i += 1) {
                        if (results[i]) {
                            if (typeof queue[i] === "function") {
                                queue[i].apply(null, results[i]);
                                delete queue[i];
                            }
                        } else {
                            return;
                        }
                    }

                    queue.length = results.length = 0;
                };
            },

            run: function (func) {
                return obj.async(func)();
            }
        };
        return obj;
    }

    return make();
}());

JavaScript is normally synchronous: it executes each line in sequence. Certain functions, however, operate asynchronously: they do not halt execution, yet you need a way to get the results at a later time. To deal with these situations, you usually pass in a callback function that is run when the asynchronous call completes.

This works rather well, until you try to mix asynchronous and synchronous code together. Consider, for example, that you are trying to make multiple calls using XMLHttpRequest. The requests themselves are asynchronous, but you want them to behave synchronously.

Here's an example to illustrate the problem better. Assume the function getURL asynchronously loads a URL and returns it's contents:

getURL("foo", function (data) {
    // do something with data here

    getURL("bar", function (data) {
        // do something with data here

        getURL("qux", function (data) {
            // do something with data here
        });
    });
});

In order to do this, you normally need to stack each asynchronous call inside the callback of the previous call! Being able to write them linearly, however, can be useful. Using this library, you can now do this:

Queue.sync(function (queue) {
    getURL("foo", function (data) {
        // do something with data here
        queue.next();
    });
});

Queue.sync(function (queue) {
    getURL("bar", function (data) {
        // do something with data here
        queue.next();
    });
});

Queue.sync(function (queue) {
    getURL("qux", function (data) {
        // do something with data here
        queue.next();
    });
});

As you can see, we're adding functions onto a queue. When an asynchronous call within the queue is done, it calls queue.next(), which then executes the next function in the queue.

An even better example is being able to synchronously execute calls within a loop:

["foo", "bar", "qux"].forEach(function (url) {
    Queue.sync(function (queue) {
        getURL(url, function (data) {
            // do something with data here
            queue.next();
        });
    });
});

The above does the same thing as before, but uses a loop to generate the three calls. This makes it trivial to add new calls: just add a string to the array. This also opens up the possibility of dynamically creating an array, and then looping over it and executing asynchronous callbacks in order.

There is one problem with the previous three examples. Although each call to getURL is asynchronous, it waits before executing the next call. It would be better to execute all the calls in parallel, but display the results sequentially. Here's an example of how to do that:

["foo", "bar", "qux"].forEach(function (url) {
    getURL(url, Queue.async(function (data) {
        // do something with data here
    }));
});

This should return the same results as the previous examples, but performs faster because the three calls are executing in parallel. To be more specific, the results are limited by the speed of the slowest call, rather than the sum of all the calls.

So how does it work? Queue.async returns a function. When that function is called, it executes (in sequential order) the results that have been found so far, making sure not to execute the same result twice. When it finds a call that doesn't have a result yet, it stops.

Where I've found this most useful is when creating extensions for Google Chrome. In the Chrome extension system, almost all of the API functions are asynchronous: you have to pass in a callback if you want to retrieve the results of the function.

Unfortunately, stacking callbacks inside of callbacks reduces readability, especially if they are deeply nested. Using the above construct, you can program in a linear style, thus avoiding race conditions while retaining the benefits of asynchronous code.

Also, if you want to push a synchronous function onto the queue, you can use Queue.run:

var results = {};

["foo", "bar", "qux"].forEach(function (url) {
    getURL(url, Queue.async(function (data) {
        results[url] = data;
    }));
});

Queue.run(function () {
    console.log(results);
});

The above executes three asynchronous calls in parallel, and when they're all done, it runs the function passed to Queue.run, which then logs the results.

Here's how you might do it if you didn't have Queue:

var results = {};

function end() {
    console.log(results);
}

var index = 3;

["foo", "bar", "qux"].forEach(function (url) {
    getURL(url, function (data) {
        results[url] = data;

        index -= 1;
        if (index === 0) {
            end();
        }
    });
});

Lastly, you can use Queue.make to create multiple queues. Ordinarily, if you use Queue.sync, only one function can execute at a time. But by using multiple queues, you can have one function executing per queue. This also lets you nest calls to Queue.sync:

var one = Queue.make(),
    two = Queue.make();

[".gif", ".jpg", ".png"].forEach(function (suffix) {
    one.sync(function (queue) {

        ["foo", "bar"].forEach(function (name) {
            two.sync(function (queue) {

                getURL(name + suffix, function (data) {
                    // do something with data here

                    queue.next();
                });
            });
        });

        two.run(queue.next);
    });
});

The above synchronously executes calls to getURL in this order:
"foo.gif", "bar.gif",
"foo.jpg", "bar.jpg",
"foo.png", "bar.png"

Why do you need two queues? Here is what the queue would look like if you used only one queue:

.gif foo bar .jpg .png foo bar foo bar

But by using two queues, it looks like this, which is what you want:

.gif foo bar .jpg foo bar .png foo bar

In this particular case, we could have used a single queue and it might have worked okay, but in a different case two queues might be necessary to avoid this issue.

12 December, 2009

Autoscroll in Chrome (Linux)

2009/12/14 Update:
AutoScroll has been submitted to Google Chrome Extensions. You can find the link at the bottom of this post. I recommend users install that one instead, so that you can receive automatic updates. This also fixes a bug where it scrolled on password fields.


Almost 5 months ago, a bug was filed on the Chromium issue tracker, asking that autoscroll be implemented in Linux.

Seeing as how it won't be implemented anytime soon, I created an extension to add this feature in. Here were my design goals:

  • Sticky and non-sticky scroll
  • Ability to customize aspects (such as scroll speed)
  • Fluid and natural behavior
  • Try to follow what Firefox (and other browsers) do

For the most part, I believe I fulfilled those goals. Try it out!

[LINK] AutoScroll Extension for Chrome.

23 August, 2009

Negation in regular expressions

2009/09/07 Update:
David Jones has posted a very simple solution to my contrived problem:

/\b(?!foo\b)[a-zA-Z]+/g
The above syntax does indeed solve the problem as laid out in this post. What I'm curious about now is if there is any situation where my proposed syntax works, and the above does not.

 

Regular expressions are highly useful things, with a variety of purposes. Nonetheless, I believe there is room to improve them. For instance, I have run across the following situation:

Let's suppose you want to find all the words in some text. This is rather simple:

/[a-zA-Z]+/g
But now let's suppose you want to find all the words, except the word "foo". This is incredibly more complicated. You can't use this construct:
/[^f][^o][^o]/g
For two primary reasons:
  1. It would match non-letter characters, like punctuation.
  2. It wouldn't match the word "boo" or "sol", even though neither are equal to the word "foo".

Let's try to rectify the first point:

/[a-eg-zA-EG-Z][a-np-zA-NP-Z]{2}[a-zA-Z]*/g
Well, now it no longer picks up punctuation, but it has grown far more complicated! And it still won't match "boo" or "sol".

What is the correct solution, then? See the update above. There mostly isn't one. You could probably come up with an incredibly long and complicated regular expression, but it's just not worth it. So, I am proposing a new syntax for regular expressions:

/[a-zA-Z]+(?^foo)/g

The above will match every word, except for the word "foo". However, it will match "boo", "sol", and "fool". On the other hand:

/[a-zA-Z]+(?^foo.*)/g
The above will match "boo" and "sol", but not "fool" or "foolhardy". This solves the problem of negation, within regular expressions.

15 July, 2009

Syntax Highlighting

In my previous post, I described the KAE.query.highlight plugin, which does syntax highlighting in JavaScript. I will now show you how I achieved this relatively easy task.

Naturally the best way is to simply grab a copy of the source, and read the code (there are plenty of comments as well). However, only a small part of the code is doing the actual parsing, so it can be easy to get lost. This post will give a general overview of the steps required.

I'm going to assume that you want to allow users to create their own rules for parsing (brushes), and also supply their own themes (for colors, etc). Here are the basic steps:

  1. Grab the brush and loop over it. Find all the matches in the source text, and store them in an array. You will need to know at least four things: the text, the CSS class, the start index, and the end index. These are all trivial to obtain.

  2. Sort the array of matches by the start index, so the matches are in the correct order.

  3. Loop over the matches. For each match, check to see if the current start index is greater than the previous end index. If so, add the match's text and apply the CSS class. If not, set the current match's end index to be the same as the previous match's end index.

    This is important because you will have matches within matches. For instance, you might have a comment. You want it to ignore the matches that are inside of the comment, obviously. This also handles things like numbers inside of strings, etc.

    Here is a diagram showing why this works:

    Let's examine it. The colored area shows the current match. The arrow shows the previous match's end index. One way to think of it is: if the arrow is to the right of the current match, we ignore the match and go to the next one.

    The important thing is that if a match is inside of the previous match, we set the current match's end index to be the same as the previous match's end index. This allows us to recurse through the entire set, rather than stopping at the first.

  4. Now, you want to use something like slice() to obtain the non-matching text in between the current match's end index, and the next match's start index. This handles things like this: Foo.bar.qux(); Note how .bar. is not a match, but we want to include it, rather than leaving it out.

That's it! No, really, that's all the parsing that's required. KAE.query.highlight's parsing code is only 30 38 lines! It also handles a few odd cases, and allows you to apply multiple brushes at the same time to the same element.

Just grab a copy of the source code and search for KAE.query.highlight.parser

That function handles all the parsing. It should also be well commented, so hopefully you won't have any trouble understanding.

KAE.query.highlight

For a long while now I had been using the wonderful SyntaxHighlighter for syntax highlighting on this blog.

I had a (possibly) odd requirement, however: I wanted to be able to syntax highlight code that was inline with non-code. Here's an example:

Blah blah blah var foo = "foo"; blah blah blah.

SyntaxHighlighter won't let you do that. I created a quick stand-alone program that would allow for inline highlighting, but that added even more bloat to an already-big program. (SyntaxHighlighter is 1,984 lines long!)

I then decided to create my own syntax highlighter. One that was designed from the ground up to be very minimal and light-weight, and one that easily supported inline highlighting. The fruit of my labor is the KAE.query.highlight plugin.

Wait. Plugin? Not program? KAE.query.highlight relies on the KAE.query module in order to function. This may seem like a disadvantage at first, but let's look at the benefits:

  1. Allows syntax highlighting on any element, not just those with a special class.
  2. Provides a platform for building other useful plugins.
  3. KAE.query plugins can easily be ported to jQuery, due to the similarities in architecture.

What is KAE.query, anyways? Think of it like jQuery without any features. You pass in a string, and KAE.query will return the DOM elements that match the string, just like jQuery. It supports a plugin system that is very similar to jQuery's plugin system. Unlike jQuery, however, it lacks any useful methods: those must be provided with plugins. In essence, it is a light-weight stripped down version of jQuery.

I don't harbor any ill feelings toward either jQuery or SyntaxHighlighter. However, both projects are targeted at something I don't need. I just wanted a simple way to extend the DOM NodeList, providing useful methods, like syntax highlighting.

Having said that, you might wonder why anybody would choose KAE.query.highlight over SyntaxHighlighter. Here are some reasons why I decided to create a new project:

  • Can be used to apply syntax highlighting with different options to different elements. For instance, you may want to apply different settings to a <code> tag than you would want to apply to a <pre> tag.
  • Much smaller in terms of code size. This can make a big difference when viewers have not cached the JavaScript file.
  • Uses a library-agnostic brush system that allows all JavaScript highlighters to use the same brushes.
  • Non-destructive: KAE.query.highlight works on the original element, so any styles are preserved.
  • Easily allows for syntax highlighting of inline elements.
  • Much much faster.

An interesting side effect of making it a KAE.query plugin is that it's backwards compatible with SyntaxHighlighter. You shouldn't need to change any HTML markup: it'll just work.

Some of these changes could be merged back into SyntaxHighlighter; in fact I encourage it. Some of the changes, however, may not be accepted.

Please do file any bugs or suggestions on the bug tracker listed below.

[LINK] Bug Tracker

[LINK] KAE.query
[LINK] KAE.query.highlight

02 July, 2009

Timer constructor.

"use strict";
var Timer = function (iter) {
    function manip(item) {
        return item;
    }
    this.average = function (func) {
        manip = func;
    };
    this.results = function () {
        var i, length = this.length, times = [];
        for (i = 0; i < length; i += 1) {
            times.push(manip(Timer.run(this[i], iter), iter));
        }
        return times;
    };
};
Timer.prototype = [];
Timer.run = function (func, length) {
    var i, start, end;
    length = length || 1;
    start = new Date();
    for (i = 0; i < length; i += 1) {
        func();
    }
    end = new Date();
    return end - start;
};

In an earlier post I described a simple function for benchmark testing in JavaScript. There isn't anything wrong with this function (aside from it being a global), however it doesn't do very much.

Most of the time, when I want to do benchmarks, I'm comparing 2+ ways of doing the same thing. This allows me to pick whichever method is the fastest. It is possible with getTime, but it is cumbersome. I then set out to create the Timer constructor, to alleviate this problem.

You initialize it with new Timer(), and you can pass in an optional number, indicating the iterations. If you create it with new Timer(1000), then every function will be called 1,000 times.

Timer is similar to an array of functions. You can add new functions with the push() method:

var timer = new Timer(100);
timer.push(function () {
    /* code goes here! */
});

You can use push() to add as many functions as you like. In order to obtain the actual time it takes to run the functions, you call the results() method, which returns an array:

// An array of benchmarks:
timer.results();

You can then call join() to display the array in various ways:

// Use custom separators:
timer.results().join("");
timer.results().join("\n");
timer.results().join(" + ");

Lastly, there's the average() method, which allows you to manipulate the benchmark. For instance, to average the results based on the mean:

timer.average(function (item, iter) {
    return item / iter;
});

You pass in a function, which is run after each benchmark has been computed. The first argument is how long it took to run the function, and the second argument is how many times the function was run (iterations). Whatever the function returns is used instead of the normal time.

Using these combined, you can create a simple script to compare two or more pieces of code, to determine which is fastest:

var timer = new Timer(10000);

//-- Begin benchmark functions
timer.push(function () {
    $("#test").css("backgroundColor", "black");
});

timer.push(function () {
    $("#test").css({
        backgroundColor: "black"
    });
});

timer.push(function () {
    $("#test").attr("style", "background-color: black;");
});
//-- End benchmark functions

timer.average(function (item, iter) {
    return item / iter;
});
alert(timer.results().join("\n"));

The above runs three functions (that do the same thing), computes how long it takes to run them 10,000 times, averages the result, and lastly displays it. If you don't want it to average the result, simply leave out the timer.average() call.

Finally, you can still access the old getTime under the name Timer.run:

var time = Timer.run(function () {
    /* code goes here! */
}, 100000);

[LINK] The source code.
[LINK] The unit tests.

26 June, 2009

Lambdas and closures.

Two of the smartest things about JavaScript are lambdas and closures, which were taken from Scheme.

Why should you care about this? Because, using lambdas and closures, you can do things that would either be impossible or difficult without. An example?

Math.random = (function () {
    var random = Math.random;
    return function (min, max) {
        return max ? (random() * (max - min + 1) + min) : random();
    };
}());

What does this allow you to do? Well, hopefully you know that in JavaScript, you can use Math.random() to return a pseudo-random float between 0.0 and 1.0. This is very useful, of course, as you can then manipulate that value in various ways.

Something I had need of is a function that will return a pseudo-random number within a range. In other words, I wanted to call Math.random(1, 6) to simulate a dice-roll (returning a number between 1 and 6).

"What? How?! You're overwriting Math.random, yet you still need to be able to call it!", you may be saying. That is all true, of course. Even though I have to overwrite Math.random, I still want access to the old version. This is possible (and easy) with closures.

First, I create an anonymous function (lambda) and execute it immediately. Inside I create a reference to Math.random in the variable random. I can now refer to the old Math.random within the anonymous function.

Because I'm assigning this to a variable, whatever the lambda returns will be put into Math.random. In this case, I return a function, which has access to the variable random. This is called a closure.

Now, within the returned function, I can use random to refer to the old Math.random, allowing me to perform all the wizardry I need. Aren't lambdas and closures wonderful?

Here's some examples of how to use it:

// Returns a pseudo-random float between 0.0 and 1.0:
Math.random();

// Returns a pseudo-random float between 5.0 and 8.0:
Math.random(5, 8);

// Returns a pseudo-random int between 5 and 8:
Math.floor(Math.random(5, 8));

Note:  Math.floor is significant. Math.round would produce incorrect numbers.

11 June, 2009

Name change to KAE Scripts.

We are now "KAE Scripts". There were various reasons for this:

  • The previous name lacked identity.
  • It also wasn't very descriptive at all.
  • Besides, why bother having the name "KAE" if you don't use it?

This solves all of the above problems. "KAE" is used in the title, thus providing identity, and "Scripts" implies some sort of scripting language (like JavaScript), giving focus and context.

HTTP.cookie

Chances are, at some point or other you'll have to work with cookies, the little pieces of data sent in HTTP requests.

Unfortunately, the way to work with cookies in JavaScript is absolutely horrible. Compounding the problem, there isn't any standard easy way to get/set a cookie, so we end up with dozens of different functions, each trying to do exactly the same thing.

Even worse, a lot of these functions (though they work), are very verbose and inefficient, making them both unwieldy and slow. If that wasn't bad enough, they often pollute the global namespace (sometimes with 3 global functions!).

As awful as dealing with cookies is, I found myself needing to do this. I had some criteria that I wanted in a cookie function:

  • Support getting/setting/deleting cookies.
  • Allow all the cookie settings, like path, domain, max-age, etc.
  • Use the same function for everything.
  • Lightweight in terms of code, and also very fast.
  • Use at most one global variable, preferably none.
  • Not tied to any libraries, making it easy to embed.
  • Simple and intuitive to use.

Nothing fulfilled all the above requirements, so I implemented my own. It uses the HTTP global variable, in case somebody wants to add another method dealing with HTTP.

You use it like this:

// Get a cookie:
HTTP.cookie("test");

// Set a cookie:
HTTP.cookie("test", "Hi!");

// Delete a cookie:
HTTP.cookie("test", null);

In addition, you can pass along a third parameter, which lets you set the special cookie settings:

// All the settings at once:
HTTP.cookie("test", "Hi!", {
    path: "/",
    domain: "temp",
    maxAge: 31536000,
    expires: new Date(2010, 0, 0),
    secure: true
});

Every setting works as you would expect. As per the specification, expires should be a GMT-string. You can pass in a string directly, or a Date object, which will then be converted into a GMT-string.

NOTE: If you set a cookie with path, domain, or secure, you must delete the cookie with the same settings. In other words: two cookies with the same name and value (but different settings) are considered as two different cookies.

[LINK] The source code.
[LINK] The unit tests.

References:
[MDC] document.cookie

08 June, 2009

arguments.callee

ECMAScript 5 strict mode has completely removed arguments.callee.

Now, there have been very good arguments both for and against arguments.callee, and I'm not going to go into them. However, what I will go into is how it changed my coding style, and also some possible perks.

Let's take an example of code that I showed in an earlier post:

var alert = function () {
    var that = arguments.callee;
    if (!that.stop) {
        that.stop = !confirm(Array.prototype.join.call(arguments, "\n"));
    }
};

Now, there isn't anything particularly wrong with this code: it works fine, and passes JSLint. However, it will surely fail in strict mode. Here is how I corrected it:

var alert = function anon() {
    if (!anon.stop) {
        anon.stop = !confirm(Array.prototype.join.call(arguments, "\n"));
    }
};

The above does the same thing, but without using arguments.callee. How is this possible? It uses a named anonymous function. Yes, yes, it's an oxymoron, but please bear with me here.

Most anonymous functions are.. well, anonymous. If you want to do any kind of recursion, you have to either name the function (polluting the namespace), or use arguments.callee.

However, in later versions of ECMAScript, we are given the ability to make a named anonymous function. This is like a combination between a named function and an anonymous function, but with a twist: the name is only usable inside of the function.

Let's test that with some code:

var foo = function bar() {
    alert(bar);
    alert(window.bar === bar);
};
foo();

Note how the anonymous function bar() is accessible within itself, but does not create a global function bar(). In addition, if we assigned this function to a different variable, bar() would still be intact!

Using this technique, we no longer have any need for arguments.callee. We can use bar() within the function to refer to itself, and nothing outside has access to bar().

An interesting side effect of this is that alert.stop is undefined. In the old way you could access alert.stop. That turned out to be harmless; but in a more critical function it could have had disastrous effects.

The primary argument against this change is that it breaks stuff in IE. Except that IE has always had severe problems. It should work just fine in any non-IE browser. Also note that this only matters if you are using strict mode. If you are in normal non-strict mode, you can still use arguments.callee.

Either way, I plan to use this technique much more often, as it has proven it's use.

02 June, 2009

Game of Life in JavaScript.

[LINK] Conway's Game of Life

I have been fascinated by the Game of Life for some time now, and recently had the idea to make it in JavaScript.

Although the idea is hardly new, I am hoping that my version will end up being faster, better, and easier to use than the others. Try selecting a Template, then hit the Start button.

NOTE: I am using canvas for performance reasons. As such, it won't work in Internet Explorer; but I am considering fixing that.

UPDATE: I have officially given up supporting this in IE. Microsoft has gone out of their way to not support the W3C Event model, despite being given plenty of time. So, until a future version of IE decides to support the standardized events: tough luck.

30 May, 2009

Coord constructor.

In an earlier post, I mentioned that I never had need for a genuine hash. Although that is still technically correct, I did end up using bits and pieces of the Hash constructor to create a Coord constructor.

Here's how you create it:

// Infinite constraints:
var coord = new Coord();

// Set constraints:
var coord = new Coord({
    top: 0,
    right: 50,
    bottom: 50,
    left: 0
});

// Unset constraints become infinite:
var coord = new Coord({
    right: 50,
    bottom: 50
});

Using the coordinate system itself is easy. You use the pt() method to get the value of a point:

// Get the value of point (0,10):
coord.pt(0, 10);

To set or delete a point, you use the chained method set():

// Set the value of (0,10) to the value 5:
coord.pt(0, 10).set(5);

// Delete the point (0,10):
coord.pt(0, 10).set();

// You can also delete like this:
coord.pt(0, 10).set(null);

By default, it has infinite constraints: you can create a new point anywhere in the coordinate system. However, if you set constraints and then try to create a new point that is outside of the constraints, it will not create the point. I use CSS syntax for familiarity.

As an example:

var coord = new Coord();
// coord.pt(-1, -1).set(1) == 1
// coord.pt(11, 11).set(1) == 1
var coord = new Coord({
    right: 10,
    bottom: 10
});
// coord.pt(-1, -1).set(1) == 1
// coord.pt(11, 11).set(1) == undefined
var coord = new Coord({
    top: 0,
    right: 10,
    bottom: 10,
    left: 0
});
// coord.pt(-1, -1).set(1) == undefined
// coord.pt(11, 11).set(1) == undefined

Using this system, you can guarantee that every point will lie within a certain range. It accepts both positive and negative numbers.

You cannot change the size of the system after it has been created. However, you can obtain the size with the size() method; which returns an object with the size properties:

var coord = new Coord({
    top: 0,
    right: 50,
    bottom: 50,
    left: 0
});
var size = coord.size();
// size.top    == 0
// size.right  == 50
// size.bottom == 50
// size.left   == 0

The coordinate system also provides a length property, that lists how many points are currently in the system. You can also use the forEach() method to iterate over each point:

coord.forEach(function (x, y, value) {
    alert("(" + x + "," + y + ") has the value: " + value);
    this.pt(x, y).set(10);
});

Note how the function is given the x, y, and value of each point. In addition, this is set to the current executing coordinate system, making it easy to use the pt() method.

You can use this to implement a Cartesian coordinate system, or augment the DOM; for instance allowing collision-detection in JavaScript.

[LINK] The source code.
[LINK] The unit tests.

28 May, 2009

Timing in JavaScript.

2009/07/02 Update:
I have created a far better version, which you can find here: [LINK]

"use strict";
var getTime = function (func, length) {
    var i, start, end;
    length = length || 1;
    start = new Date();
    for (i = 0; i < length; i += 1) {
        func();
    }
    end = new Date();
    return end - start;
};

JavaScript does not have a built-in way to easily measure how long it takes to run code; however, it supplies the necessary building-blocks to create such a way.

You use getTime like this:

var time = getTime(function () {
    /* code goes here! */
}, 100000);

The variable time now contains how many milliseconds it took to run the function 100000 times.

  1. The first parameter should be a function. The time it takes to run this function is returned.
  2. The second parameter is how many times you want to run the function. The default is 1.

Using this function, you can easily see how long it takes to run chunks of code, which is useful in benchmarking.

Constructors and "this".

2009/08/14 Update:
It has come to my attention that there is a better way of doing this:

var Point = function (x, y) {
    if (this === window) {
        return new Point(x, y);
    }
    this.x = x;
    this.y = y;
};
Although this article is still useful, please use the above, instead of using call.


The this keyword in JavaScript is very powerful, when used correctly. Unfortunately, JavaScript has a bit of infatuation with the global scope, so most of the time this isn't very helpful at all.

You can rebind this with the methods call() and apply(). Ordinarily, you wouldn't want to do this; however, there is one interesting case.

JavaScript constructors look like this:

// Constructor:
var Point = function (x, y) {
    this.x = x;
    this.y = y;
};

// Instance:
var point = new Point(10, 5);

When you use the new keyword, this is bound to the newly created object, which makes it easy to set up properties on the new object.

However, if you fail to use the new keyword, this will bind the properties to the global object! This is a serious mistake. You can correct this with call() or apply().

Now you can write your constructors like this:

// Constructor:
var Point = function anon(x, y) {
    if (this === window) {
        return anon.call({});
    }
    this.x = x;
    this.y = y;
    return this;
};

// Instance:
var point = new Point(10, 5);

// Instance:
var point = Point(10, 5);

The if and return this; statements are mandatory. This is used to ensure that if you accidentally leave off new, it will not bind the properties to the global object.

Of course, you could have written it like this:

var Point = function (x, y) {
    return {
        x: x,
        y: y
    };
};

Which has the same effect. However, now you give up the ability to use call and apply to change the this binding. In addition, you can't use prototypical inheritance anymore! If you don't care about that, then feel free to write your constructors without this.

However, if you do care, then you can use the above construct to allow the use of this, without worrying about binding to the global object.

This will no longer apply in ECMAScript 5 strict mode, which throws an error when you try to use a constructor without new.

26 May, 2009

JavaScript associative arrays.

JavaScript does not have a distinct "hash" type: all objects are hashes, including arrays, functions, etc. Due to this extreme flexibility, most people can get by without ever needing a so-called "associative array."

The problem with objects being hashes is that it tends to "break" the for-in loop. If you add a property to the prototype chain of an object, it will be enumerated in for-in loops. You can, of course, use an if statement to filter out the prototype chain, but this is cumbersome.

Enter the Hash constructor. I personally have never had need for a genuine hash, but I had fun making this, and hope it's useful for somebody. My goal was to implement a simple and lightweight system that would make use of closures and interfaces.

You initialize it with new Hash(), and you can pass along an object as a shorthand.

var hash = new Hash();
hash.key("test", "Hi!");

Is the same as:

var hash = new Hash({
    test: "Hi!"
});

Each instance of the Hash constructor has it's own private variable values, which you cannot touch. Instead, you use the key() method to read, write, and delete values. It works like this:

hash.key("test");
// Get the value of the key "test"

hash.key("test", "Hi!");
// Set the value of the key "test"

hash.key("test", null);
// Delete the value of the key "test"

If you specify only one argument, it will return the value in the key. If you specify two arguments, it will set the value of the key. If you set a key to the value null, it will delete the key, so it no longer exists.

In addition, every Hash instance has a length property (like an array) that will tell you how many keys are in the hash. You are free to set this property to whatever you want (or even delete it), but it will have no effect. The actual length is a private variable; so next time you set or delete a key, the length property will be overwritten with the correct length.

This is all very nice, of course, but I went a step further: a forEach() method. This method will loop over the keys in the hash, and run the function you specify on each one. The two arguments it passes are the name and value of the key. In addition, this is bound to the current hash, making it easy to manipulate the keys.

Here's an example of a simple way to delete all the keys in a hash:

hash.forEach(function (name) {
    this.key(name, null);
});

And here's a way to obtain the name and value of all the keys in a hash:

hash.forEach(function (name, value) {
    alert("Key " + name + " has the value: " + value);
});

[LINK] The source code.
[LINK] The unit tests.

09 May, 2009

The && and || operators.

In JavaScript, the && and || operators are used as short-hands for conditionals. For instance:

if (foo) {
    if (bar) {
    }
}
Can be written much more succinctly like this:
if (foo && bar) {
}
And:
if (foo) {
} else if (bar) {
}
Can be written like this:
if (foo || bar) {
}
That's great and all, but these two simple operators hold even more power to them. Let's look at exactly how they function:
  • && returns the first operand if it can be converted to false; otherwise, returns the second operand.
  • || returns the first operand if it can be converted to true; otherwise, returns the second operand.

The key thing to note here is the second clause. && and || do not always return boolean values! That works out okay, because JavaScript has the concept of truthy and falsy values, which is a fancy way to say that anything can be easily converted into true or false.

"What are you talking about? Why should I care about this?", you say. Let's look at some examples of code, and show how the && and || operators can help us out.

if (foo) {
    foo.bar();
}
Okay, looks simple enough. We don't know whether foo exists at runtime or not, so we have to wrap the statement foo.bar() in an if. However, the following code is identical:
foo && foo.bar();

"Huh? What's going on here?" As stated above, the && operator returns the second operand if the first operand is truthy. In addition, if the first operand is falsy, the second operand isn't even evaluated!

In other words: foo.bar() is only called if foo is truthy.

What exactly is truthy and falsy? A value in JavaScript is falsy if it is undefined, null, false, the empty string "", NaN, or the number 0.

Everything else is truthy, including an empty object {} and empty array [].

"Fine, so I can save a couple lines by using the && operator, who cares?"

Let's make this example a little more complicated by using a more deeply-nested object:

if (foo) {
    if (foo.bar) {
        if (foo.bar.qux) {
            foo.bar.qux.corge();
        }
    }
}
Oh my! Look at all the nested ifs! Now, we could have written it like this:
if (foo && foo.bar && foo.bar.qux) {
    foo.bar.qux.corge();
}
Or even more succinctly:
foo && foo.bar && foo.bar.qux && foo.bar.qux.corge();

Whichever you use will depend on your personal preferences. I'm not here to convince you to use the logical operators in this way, merely to point out that some people do use them this way. So next time you see something like the code above, you'll know what's going on, rather than being confused.

Now, the || operator can be used to select the "default" value of a variable. What do I mean by this? Well, imagine you have a function that accepts arguments, but some arguments are optional. Here's an example:

function foo(a, b, c) {
    if (!c) {
        c = 10;
    }
}
Now, there's nothing wrong with this, but you can save some characters by doing it like this:
function foo(a, b, c) {
    c = c || 10;
}

Using the above code, the variable c will supply the default value 10 if c is not specified when calling the function.

As stated above, my goal is not to convince you to use these techniques, merely to point them out so you'll understand what's going on when you read other people's code.

28 April, 2009

Essential JavaScript functions.

2009/07/22 Update:
Added Object.keys. Removed String.prototype.*, alert, and waitUntil.
"use strict";
if (typeof Object.create !== "function") {
    Object.create = function (o) {
        function F() {}
        F.prototype = o;
        return new F();
    };
}
if (typeof Object.keys !== "function") {
    Object.keys = function (obj) {
        var name, output = [];
        for (name in obj) {
            if (Object.prototype.hasOwnProperty.call(obj, name)) {
                output.push(name);
            }
        }
        return output;
    };
}

The above are functions I have found indispensable or extremely useful in my programming. They are listed here for convenience.

Object.create

String.prototype
window.alert
window.waitUntil

[LINK] The source code.
[LINK] The unit tests.

window.waitUntil

2009/08/23 Update:
This is only really useful if you need to do asynchronous calls 11 or more times. If you only need to make a few calls, it would be better to just use the (function () {}()); construct.

Here is a new function I have recently created:

"use strict";
var waitUntil = function anon(func, ms) {
    ms = ms || 100;
    if (func() !== true) {
        return setTimeout(function () {
            anon(func, ms);
        }, ms);
    }
};

I don't know about you, but in my code I have to frequently test a condition... but do so asynchronously. You can do this with setTimeout, but it requires a lot of syntax and work to get it right. The above function attempts to ease this a little.

You call it like so:

waitUntil(function () {
    if (test === 5) {
        alert("Done!");
        return true;
    }
});
This is the same as if I had done:
(function anon() {
    if (test === 5) {
        alert("Done");
    } else {
        setTimeout(anon, 100);
    }
}());

Not a huge difference, but still useful when you need to perform such checks on a regular basis. waitUntil accepts two arguments:

  1. This should be a function. waitUntil will continue executing this function until it returns true, which tells waitUntil to stop.
  2. This should be a number. This is how often waitUntil will run the function, in milliseconds. The default is 100.

In addition, waitUntil returns a setTimeout, so you can use clearTimeout to halt the check at any time:

var timer = waitUntil(function () {
    if (test === 5) {
        alert("Done!");
        return true;
    }
}, 300);
clearTimeout(timer);

[LINK] The unit tests.

window.alert

One of the problems with the alert() function is the inability to cancel it when placed within loops. You may find this function useful:
"use strict";
var alert = function anon() {
    if (!anon.stop) {
        anon.stop = !confirm(Array.prototype.join.call(arguments, "\n"));
    }
};
These following lines of code are identical:
// Old:
alert("Hi!");
// New:
alert("Hi!");
// Old:
alert(1 + "\n" + 2 + "\n" + 3);
// New:
alert(1, 2, 3);

However, an even more powerful feature of this new alert() function is that if it is called repeatedly, you can click the "Cancel" button to prevent it from displaying any more alerts!

Credit for the idea goes to this blog. The actual code is all by me, though.

[LINK] The unit tests.

12 April, 2009

Reflecting a vector.

Let us assume:
angle = the angle of the incoming vector.
 wall = the angle of the "wall".

The formula for the reflection of an incoming vector in degrees is:
angle - (2 * (angle + (90 - wall)))
There is also a version in radians, which is very similar:
angle - (2 * (angle + ((PI / 2) - wall)))