Skip to content

Coding Conventions

jussi-kalliokoski edited this page Mar 31, 2012 · 5 revisions

This page is about the conventions to apply when coding stuff for audiolib.js. Some of it is best practices, some about preferences, some about premature optimization, so if you apply these conventions outside audiolib.js, please apply proper criticism.

Style & formatting

I will probably accept pull requests with improper formatting, and change them myself, but if you want to be a nice open source citizen, you should follow these rules:

  • Hard tabs
  • Tab width === 8 columns
  • For vim, you can do :set tabstop=8 softtabstop=8 shiftwidth=8 noexpandtab
  • If you're doing multiple assignments, use tabs before assignment, so that the assignment symbol is always on the same column. In the case of object notation, apply the tab after the assignemnt symbol. Like this:
var a   = 1,
    b   = 2,
    c   = 3;

var     x   = {
    a:  1,
    b:  2,
    // it's NOT ok to use comma after the last items in objects!
    c:  3
};
  • Curly brackets open always on the right side, and weird rules for spaces, like this:
function () {
    if (a) {

    } else if (b) {

    } else {

    }
}

var x = {
};

// for long arrays, use the same convention with square brackets

var y = [
    1,
    2,
    3,
    // For arrays, don't use colons after the last item either.
    4
];
  • Define all variables at the start of the function.

Best Practices and (Premature) Optimization

  • Always use === over == unless you have a REALLY good reason. === is always more reliable and faster.
  • Use prototypes where possible, the less instances of objects and functions you have, the better for performance.
  • NEVER use lookup tables when there is a function designated for the action. Memory might have been faster than computing in the 1980s, but it never has been for JavaScript, and probably never will be. So it's premature, and not even optimization to use lookup tables.
  • If you think you should be defining variables inside a loop, the loop should probably be in a function of its own. This also makes it easier for caching optimizations – such as CrankShaft – to be faster, so it's also partly premature optimization, but I think it will hold true in the future as well. It also looks better, so why the hell not.
  • You can localize variables quite freely, but do it in the name of readability and size optimization rather than runtime speed. Localizing variables does – however – speed up memory access in older JavaScript engines, but it falls in the category of bad premature optimization, because it can actually slow stuff up in some cases (for example, when Typed Arrays become faster, if you localize a value and then put it back there, you're doing unnecessary memory copying and type conversion). Do only when you can think of other reasons than speeding up the memory access.
  • Reuse variables. This goes well with the previous notes. This helps with size and making it easier for the garbage collection (and boy do we want light GC to avoid pops and cracks).
  • Avoid unnecessary checks, because in audio processing, everything you do gets iterated quite a lot. If you want to optimize your code in a future proof manner, the way to go is to do less. So for example, if you're doing it like this:
function myEffect () {
}

myEffect.prototype = {,
    i: 0,
    pushSample: function () {
        if (this.i < 10000) {
            this.i++;
        } else {
            // Do stuff
        }
    },
    getMix: function(){}
};

do it like this instead, it's JavaScript:

function myEffect () {
}

myEffect.prototype = {,
    i: 0,
    _pushSample: function () {
        // Do stuff
    },
    pushSample: function () {
        if (this.i < 10000) {
            this.i++;
        } else {
            this.pushSample = this._pushSample;
        }
    },
    getMix: function(){}
};

and there, checks avoided when not needed.

Something went wrong with that request. Please try again.