JavaScript prototype gotchas

JavaScript is a strange language:

12345678910
MyClass = function() {};

MyClass.prototype.myProperty = [];

var a = new MyClass();
var b = new MyClass();

a.myProperty[0] = 'xyz';

console.log(b.myProperty[0]); // prints 'xyz'

The issue here is one of prototypes and references. In most OO languages, defining a property on a class is done so in such a way that each instance of that class has a property completely independent of all other instances. Even if it's a reference, it still gets a reference to its *own* value.

In JavaScript, things are a bit wacky. Mostly they work as normal (with strange syntax), but occasionally things like this trip you up. It happens because, as you can see, both a and b have a reference to the same object; the one assigned to the prototype. This is only a problem with 'rich' types like arrays and objects, immutable types like string and primitives sort themselves out.

The way to avoid it is to assign 'myProperty' within the constructor:

123
MyClass = function() {
    this.myProperty = [];
};

It's strange that JSLint doesn't pick up on this.

For what it's worth, gjslint (Google's closure linter) will emit:

Line 3, E:0100: Member MyClass.prototype.myProperty cannot have a non-primitive value

but I find Google's linter is generally not as universally useful as JSLint (it's better for Closure development though, i.e. if you're planning to feed your source through the Closure Compiler).

Talk is cheap

Leave a comment:

HTML is not valid. Use:
[url=http://www.google.com]Google[/url] [b]bold[/b] [i]italics[/i] [u]underline[/u] [code]code[/code]