Javascript: adding a unique ID to every object

This entry is about Javascript, not Perl. It's about object identity in particular.

If you have two objects in x and y, you can check whether they're really the same object with x === y. However, as far as I know Javascript provides no way to get an object's address (which you could use as a key in a hashtable or whatever). The following code attempts to fix this problem by adding a unique ID to every object (and I do mean "every"):

var enchant = (function () {
    var k = 'id';
    var uniq = 0;

    return function enchant(o) {
        var t = uniq++;
        Object.prototype.__defineGetter__.call(o, k,
            function () {
                return this === o ? t : enchant(this, k);
            }
        );
        return t;
    };
}());

enchant(Object.prototype);

Now each object foo has a (unique) foo.id property.

I've only tried this in Mozilla's Javascript engine, so I wouldn't be surprised if this completely fails to work in anything but Firefox (or at least Internet Explorer). It's not hard to make this code portable though, at the expense of the "nice" foo.id syntax; you have to write foo.id() instead:

var enchant = (function () {
    var k = 'id';
    var uniq = 0;

    return function enchant(o) {
        var t = uniq++;
        o[k] = function () {
            return this === o ? t : enchant(this, k);
        };
        return t;
    };
}());

enchant(Object.prototype);

Anyway, I think this is a pretty cool hack. But to be honest, it feels like the equivalent of Acme:: code: fun and thought provoking, but not necessarily something for real-world use.

1 Comment

Agreed, pretty cool hack. Nice to know that we can do tricks like this in Javascript.

Leave a comment

About mauke

user-pic I blog about Perl.