Hi-performance Javascript Tips #2 «Revisited»

In a previous post, we recreated a simple version of Java’s StringBuilder:

var StringBuilder = function (str) {
    var _stack = str ? [str] : []; // str == initial string to start, if any
 
    // append can take one or more strings as arguments
    this.append = function () {
        _stack.push.apply(_stack, arguments);
        return this;
    }
 
    this.toString = function (separator) {
        return _stack.join(separator || '');
    }
}

Unlke Java’s implementation, we’ve added a separator parameter to the toString() method. This would be very helpful in creating HTML or CSV using our object.

I was thinking it would be fun to add a few more features of Java’s StringBuilder onto our decidedly simple example. Here’s how we could add a separator property and a length property (with setter and getter):

var StringBuilder = function (str) {
    var _stack = str ? [str] : [], // str == initial string to start, if any
        _length = str.length; // length of initial string
 
        this.separator = ''; // separator used when concatenating strings in the stack
 
    // public methods 
 
    this.append = function () {
        // append can take one or more strings as arguments
        _stack.push.apply(_stack, arguments);
        toArray(arguments).forEach(function (str) { _length += str.length });
        return this;
    }
 
    this.getLength = function () {
        return _length;
    }
 
    this.setLength = function (len) {
        // coalesce what we've already got and cut it to length
        // Note: this does not expand the string. it only clips it.
        _stack = [_coalesce(this.separator).substr(0, len)];
        _length = len;
        return this;
    }
 
    this.toString = function (altSeparator) {
        return _coalesce(altSeparator == undefined ? this.separator : altSeparator);
    }
 
    // private methods
 
    function _coalesce (separator) {
        // consolidates all of the string entries into one string
        var str = _stack.join(separator || '');
        _stack = [str];
        _length = str.length;
        return str;
    }
}

See my previous post for the implementation of toArray. Unfortunately, IE 6 & 7 are pitifully behind the rest of the Javascript world and need additional help. See the following article from Mozilla for implementing the forEach iterator method in IE:

forEach

toArray

There’s a potentially nasty side-effect in the setLength() method. If you were planning to use the altSeparator parameter in the toString() method, but you use the setLngth() method first, the separator property will be used instead! Either we should create excellent documentation; write a somewhat slower, but safe implementation of setLength(); or remove the altSeparator parameter (and possibly the separator property) and move it to the constructor.

Sample output:

var sb = new StringBuilder('fun');
sb.append('stuff', 'with', 'javascript');
sb.separator = ' ';
sb.setLength(10);
'string="' + sb.toString() + '" length=' + sb.getLength();
 
"string="fun stuff " length=10"

One thought on “Hi-performance Javascript Tips #2 «Revisited»

Comments are closed.