If I have a javascript class which cannot be instantiated what should the constructor return that I can test for. The constructor always returns an object so I cannot return null if the constructor fails.
function SomeClass(id) {
if(typeof(id) === 'number' {
// This is good
this.id = id;
} else {
// This is bad
// This return is ignored and an empty object is returned
return null;
}
}
var a = new SomeClass('badParam');
if(a){
// is true even though the class expects a number.
}
// Could use this check
if(a.id !== undefined){
// Do some stuff
}
but it seems there should be a better way.
It is probably best to throw an exception to notify the caller that the initialization failed and to take appropriate action.
Return codes are fine, but for the most part there is no motivation for the caller to implement the checks on the return code.
My advice is to break hard and break soon. This will make contract violations very evident during testing.
Returning any non-object from the constructor is practically the same as exiting the constructor. (The constructor will return a new object, with a prototype
if one was specified.)
So, returning null
, undefined
, or 42
from the constructor are equivalent.
Check out section 13.2.2 of the ECMAScript spec (pdf) for more info.
My first approach:
- Don't allow a constructor to fail; consider alternatives
My second approach:
- If a constructor fails, it must only fail because of a programming error and thus;
- should throw an exception and;
- must not return 'a status code' (see Emmett's answer for why returning
null
doesn't work anyway)
I have never designed a constructor (something invoked as the target of new
) to return anything except an object of the "expected" type.
Fail fast, avoid being too clever, and save time debugging hard-to-find bugs.
Happy coding.
Use I sentinel. I like to
return {invalid:true};
This looks clean:
var x = new X();
if (x.invalid) { // ...
(There's no way to return a non-true value from a constructor, so you can't put new in the conditional as you might with another language.)