Fixing Object Instances in JavaScript
Do you know your JavaScript? Take a look at the following code sample and work out what value is shown in the final alert statement …
// object constructor
function ObjectConstructor(a, b, c) {
this.A = a;
this.B = b;
this.C = c;
this.Total = a + b + c;
}
var obj = ObjectConstructor(1, 2, 3);
alert(obj.Total);
Hands up everyone who answered “6.”
Sorry, you’re wrong. The answer is … nothing — or an error stating that ‘obj’ is undefined. So what’s gone wrong?
The simple answer is that we’ve forgotten the ‘new’ operator so an object instance is never created. The statement should be:
var obj = new ObjectConstructor(1, 2, 3);
It’s an easy mistake to make. Novice developers are unlikely to spot the missing operator because the code looks almost identical. Even experienced coders could find it tough to debug (especially since many assume JavaScript is a procedural programming language … which it can be, if you choose to write it that way).
The main problem is that var obj = ObjectConstructor(1, 2, 3);
is a perfectly valid JavaScript statement and the interpretor engine will not throw an error. In that context, the value of obj is set to the value returned from the function ObjectConstructor; since no value is returned, obj remains “undefined” (a top-level JavaScript property).
This is unlikely to become a major problem if you’re developing, testing and debugging your own code. However, it could be a different matter when you’re providing a library or API to thousands of third-party developers. At some point, someone, somewhere, will miss that ‘new’ operator and they will blame your code rather than theirs.
Fortunately, JavaScript is a flexible language. We can fix our constructor so an object is correctly created even when the ‘new’ operator is omitted:
// object constructor
function ObjectConstructor(a, b, c) {
if (!(this instanceof arguments.callee)) {
return new ObjectConstructor(a, b, c);
}
this.A = a;
this.B = b;
this.C = c;
this.Total = a + b + c;
}
The additional ‘if’ statement at the top of the constructor checks whether ‘this’ is an instance of the object and returns one if necessary. The code var obj = ObjectConstructor(1, 2, 3);
will now set obj to an object instance and “6” will be output by the alert statement.
Have you ever encountered this problem in your code or when using another library?