Color by numbers: dojo.delegate

I wrote a fairly advanced article over at the SitePen blog on metaclass programming. But you shouldn’t have to read through a long, technical article to find out about just one of the little gems mentioned in it. Sounds like the perfect time for a Dojo Campus cookie.

I’m about to post a fun little analogy that I wrote for the article, but it needs a little bit of explaining first. A little problem that I run in to when writing JavaScript is that I’ll have an object that I want to pass to some other function or piece of code, but I’m worried that it might get manipulated somehow by this other code and be ruined. A possible solution to this would be to create a new object and copy all the fields in, like this:

var newObject = {};
for(var key in oldObject){
 newObject[key] = oldObject[key];
}

Or you might use Dojo’s shortcut function to do the same thing:

var newObject = dojo.mixin({}, oldObject);

What you might not know is that doing the kind of for loop shown above, which is the same one that dojo.mixin does, is very time consuming. The more properties in your object, the more time consuming it is. You probably know what I’m going to say: there’s a better way to do this.

There is, it’s called dojo.delegate, you use it like this:

var newObject = dojo.delegate(oldObject);

What does delegate do? I think it’s best explained through that analogy I mentioned (taken from my SitePen article):

Let’s say that you’ve just bought a color-by-numbers book, you bring it home, and you get in trouble with your nephew who also wants to use it. But you don’t feel like driving back to the store and if you color it in, you’ve just ruined it for your nephew. But you have an idea. You take out a sheet of transparency paper, tape it over the page, and start filling it in.

In the same way, think of our original object as a color-by-numbers page that’s been partially filled in. And think of dojo.declare as putting transparency paper over our original object. Now when we write variables to this new object, or “color it in”, those changes don’t make it through to the original object. Writing a variable to the new object that doesn’t exist in the original is like coloring on the transparency sheet over a blank area. Writing a variable to the new object that exists in the original is like coloring on the transparency sheet over an area that’s already been filled in. Neither action changes what’s on the page beneath, but coloring over something means we won’t be able to see what was there originally any more.

Maybe you already figured out why this is so much faster than using a for loop or dojo.mixin to copy the properties. Since dojo.delegate is just adding a protective layer to your original object, it doesn’t have to copy anything at all! This means no for loop, no copying properties, just this one simple addition. Even if you’re copying an empty object, dojo.delegate is still faster than a for loop. But on top of that, it never gets any slower, no matter how big your original object is, while the for loop approach slows down.

Also, you can keep using dojo.delegate to protect your properties:

var newObject = dojo.delegate(oldObject);
newObject.foo = "foo";
var newestObject = dojo.delegate(newObject);
newestObject.foo = "bar";

I hope you think to use this technique next time you want to protect an object from getting changed. It’s useful, and it’s fast!

Tags: ,