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.