2012-11-08 24 views
5

说我想要创建以下API:使新的关键字可选

var api = function(){} 

api.prototype = { 
    constructor: api, 
    method: function() { 
    return this; 
    } 
}; 

现在,这会像:

var myApi = new api(); 
myApi.method(); 

但是,让我们说,我想使new关键字可选,因此,这将工作:

api().method(); 

我会出我的头做:

var api = function() { 
    if (!(this instanceof api)) { 
    return new api(); 
    } 
}; 

但是我想知道,这可能很容易被感染,或者是否有其他危险使用此方法?我知道f.ex jQuery不会这样做(它们将构造函数卸载到原型方法),所以我确信没有这样做是有好理由的。我只是不知道他们。

+1

您的解决方案看起来非常好,我已经看到在许多地方使用。例如,参见[这里](http://ejohn.org/blog/simple-class-instantiation/)。 – bfavaretto

回答

2

在构造函数中返回一个对象。

function Car(){ 
    var obj = Object.create(Car.prototype); 
    obj.prop = 1; 
    return obj; 
} 
Car.prototype = { 
    method: function(){ } 
}; 

//test 
var car1 = Car(); 
var car2 = new Car(); 
+0

'Object.create(...)'特别好,因为它在查询时使用了强制转义,并且消除了构造函数中对'this'的任何引用,所以你不需要推断构造器上下文中的this是什么。方法仍然可以按预期访问'this'。 – Eric

-1

挑一个或另一个约定。如果您想为API句柄使用对象,但不想让人们使用new,请使用两个函数。 Api()这是一个对象的构造函数,而api()这是一个正则函数,它只是返回一个新的Api实例。

我不认为你提出的建议存在危险,这似乎毫无意义,我不喜欢一个函数同时做两件事的想法。

+1

使用'new'可选可让团队以符合其惯例的方式使用API​​。有些团队因为它的陷阱而强烈反对'new',而另一些团队则用它来表达与继承语言类似的感觉。如果API不强制团队打破这种惯例,那将会很不错。 Express.js的'Router'类是可选'new'的一个很好的例子。 – Eric