Archive for March, 2006

Update to “Inheritance in JavaScript”

Sunday, March 26th, 2006

Surprisingly, I’m seeing more and more traffic to my “Inheritance in JavaScript” tutorial. As that traffic has increased, there have been a number of legitimate complaints about my use of an “init” method to initialize base classes and child classes. I found a way around that last October, so I thought it was high time to incorporate that approach into the tutorial. So, if you find C#/Java-style OOP in JavaScript interesting (or at least not offensive), then you may enjoy my latest updated tutorial.

http://www.kevlindev.com/tutorials/javascript/inheritance/index.htm

Special thanks go to Robin Debreuil - aka. The Prototype Master - for suggesting how to get around the use of “init”. Also, special thanks to Peter Michaux (and many others) for gently prodding me to update my tutorial.

JSDrawing Now Supports VML

Monday, March 20th, 2006

I was reading through some of today’s posts over at svg-developers and I came across Mark Finkle’s blog post about his SVG in IE project. He has a nice demo showing a client-side conversion of SVG to VML via behaviors. In an earlier post, he mentions that he was inspired by Emil Eklund’s Canvas in IE project. (It seems like everyone’s transcoding these days). I had been wanting to add VML as a supported renderer, so with the help of these two fine examples, I added VML support today:

Unforunately, this means that neither IE, FF, nor Opera can render all formats. However, amusingly enough, DIV’s are still the only cross-platform rendering target.

Repeated Strings

Saturday, March 18th, 2006

A while back I was looking for a method in Java that allows me to repeat a string a certain number of times. There is a String constructor in .NET that implements this feature and I was hoping to find that in Java: no luck. The conversation ended up coming around to tricks we’ve seen in JavaScript.

Naive Approach

This first example is what I think many people would write as a first pass. This looks reasonable and is straight to the point. However, it is expensive to concatenate strings in a loop like that. The script engine has to allocate a new string for the concatenation, copy the old value into the new string, and copy the appended value into the string. You’ll really start seeing slow downs (O(n^2)) with this approach as the count increases

function repeatString(string, count) {
    var buffer = “”;
   
    for (var i = 0; i < count; i++) {
        buffer += string;
    }
   
    return buffer;
}

Better Approach

This next example avoids the string allocation and copy issue by storing each string instance as an element within an array. We simply join the array using an empty string as a delimiter. The idea here is not only are we avoiding repeated allocations and copies, but we’re using the native join implementation for speed.

function repeatString(string, count) {
    var buffer = [];
   
    for (var i = 0; i < count; i++) {
        buffer.push(string);
    }
   
    return buffer.join("");
}

Nice Hack This last example was suggested by Robin Debreuil. Keep in mind that if we can get the script engine to do the hard part for us, then we get a big speed advantage. Robin’s approach is to remove the loop. First we allocate an array that contains (count + 1) elements. Finally, we join using our string as the delimiter. Each element in the array is undefined, so they don’t contribute to the final string and since we have (buffer.length - 1) delimiters, we end up with (count + 1 - 1) or (count) instances of our string.

function repeatString(string, count) {
    var buffer = new Array(count + 1);
   
    return buffer.join(string);
}