How to return null from a constructor named new in Javascript?

I try to force the constructor to interrupt the construction of the object if something fails, for example, it cannot capture the canvas.

But since I use new , I see that klass () always returns this regardless of any null return value or any other value, can I get around this to return null?

Now that I think the solution may be to create a new instance inside klass () and return that instance or null, rather than using new , is there a better solution?

 function klass( canvas_id ) { var canvas = document.getElementById( canvas_id ); if( ! ( canvas && canvas.getContext ) ) { return null; } } var instance = new klass( 'wrong_id' ); console.log( instance, typeof instance ); 
+8
javascript
source share
5 answers

Instead, you can make a "factory function" or a "static factory method":

 Foo.CreateFoo = function() { // not to confuse with Foo.prototype. ... if (something) { return null; } return new Foo(); }; // then instead of new Foo(): var obj = Foo.CreateFoo(); 

The same with the syntax of a newer class:

 class Foo { static CreateFoo() { if (something) { return null; } return new Foo(); } } 
+12
source share

A better solution would be to throw an error:

 function klass(canvas_id) { var canvas = document.getElementById( canvas_id ); if( ! ( canvas && canvas.getContext ) ) { throw new Error('Not a canvas'); } } // later... try { var c = new klass("canvas_id"); } catch(E) { // error caught } 

EDIT: Constructors may be "forced" not to return an instance:

 function Foo() { var canvas = ...; if ('undefined' == '' + Foo.CANVAS_CHECK) Foo.CANVAS_CHECK = ( canvas && canvas.getContext ); if (!Foo.CANVAS_CHECK) return []; // the constructor will actually return an empty array // passed; initialize instance here } // later on... var foo; if (!((foo = new Foo()) instanceof Foo)) { // Failed. Canvas is unsupported. } // You happy now, am not i am? ;-) 

However, it is strange that if the "constructor" returns a number, a string, true , false , etc., it actually returns an instance. The second solution only works when the constructor returns an empty array [] or an empty object {} .

+10
source share

You can use a combination of factory with a constructor in one function using the method described in an article by John Resig . Example:

 function Person(name) { var me = arguments.callee; if (!(this instanceof me)) { // factory code // validate parameters.... if(!name.match(/^[az]+$/)) return null; // ...and call the constructor return new me(arguments); } else { // constructor code this.name = name; } } a = Person("joe") // ok b = Person("bob") // ok c = Person("R2D2") // null 
+2
source share

The answer, unfortunately, you cannot: (. Reasons for this answer:

What values ​​can return to the constructor to avoid returning?

0
source share

As I posted in my comment above ...

 function klass( canvas_id ) { var canvas = document.getElementById( canvas_id ); if( ! ( canvas && canvas.getContext ) ) { return new Boolean; } } var instance1 = new klass( 'wrong_id' ); if(!(instance1 instanceof klass)) console.log( 'Canvas is not suppored' ); var instance2 = new klass( 'wrong_id' ).valueOf(); console.log( instance2, typeof instance2 ); if(instance2 !== false) console.log( 'Canvas is supported, yeah' ); 
0
source share

All Articles