我正在尝试使构造函数在某些内容失败时中止对象构造,例如它无法获取画布。
但是当我使用new
时,我发现klass()始终返回this
,无论是否返回null或任何其他值,我可以解决此问题以返回null吗?
现在我想到,一个解决方案可能是在klass()中创建新实例并返回该实例或null,而不是使用new
,是否有更好的解决方案?
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 );
答案 0 :(得分:12)
更好的解决方案是抛出错误:
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
}
编辑:可以“强制”构造函数不返回实例:
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? ;-)
但奇怪的是,如果“构造函数”返回一个数字,字符串,true
,false
等,它实际上会返回一个实例。第二个解决方案仅在构造函数返回空数组[]
或空对象{}
时才有效。
答案 1 :(得分:12)
您可以改为使用“工厂功能”或“静态工厂方法”:
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();
使用较新的类语法相同:
class Foo {
static CreateFoo() {
if (something) {
return null;
}
return new Foo();
}
}
答案 2 :(得分:3)
您可以使用John Resig's article中描述的技术在一个函数中将工厂与构造函数结合使用。例如:
function Person(name) {
var me = arguments.callee;
if (!(this instanceof me)) {
// factory code
// validate parameters....
if(!name.match(/^[a-z]+$/))
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
答案 3 :(得分:0)
答案很遗憾,你不能:(。原因在于答案:
What values can a constructor return to avoid returning this?
答案 4 :(得分:0)
正如我在上面的评论中发表的那样......
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' );
答案 5 :(得分:0)
我遇到了同样的问题:
...
function MyConstructor ()
{ ...
let Null = { valueOf: ()=>null }
return Null;
}
构造函数不能返回null。但它可以返回任何Object,因此它可以返回上面定义的对象'Null'。然后,构造函数的调用者只需在使用结果之前调用valueOf():
let maybeNull = (new MyConstructor (maybeArg)) . valueOf();
这是有效的,因为valueOf()是一个内置的JavaScript方法 默认情况下,除了盒装数字之外的所有内容 盒装字符串和盒装布尔回归自己。
您可以覆盖任何对象的valueOf(),就像我上面所做的那样 对于我的Null(),返回null。