我一直在研究使用工厂函数作为JavaScript中构造函数的替代方法。我的大多数研究都源于Eric Elliot在其博客文章中提供的信息,例如:
http://ericleads.com/2012/09/stop-using-constructor-functions-in-javascript
虽然我同意这里所说的大部分内容,但我确实错过了构造函数的自动初始化方面,所以我想在我的工厂函数中实现类似的东西:
var myFactory = function (options) {
var inst = _.create({
initialize : function (options) {
var allowedProps = ['name', 'type'];
this.options = options;
_.extend(this, _.pick(options, allowedProps));
},
test : function () {
if(this.type === 'alpha') {
return true;
}
return false;
}
})
inst.initialize.call(inst, options);
return inst;
};
var x = myFactory({ name : 'shiny', type : 'alpha' });
var y = myFactory({ name : 'happy', type : 'beta' });
1)这种行为本身只是重新引入构造函数带来的一些问题吗?
2)我通过使用'选项扩展实例来违反开放/封闭原则。在initialize方法中?它可以用于扩展(它可以用作原型),但我也可以通过“选项”修改原型本身。
我对这种模式感觉不好,觉得我应该对消费者进行初始化控制。它受到Backbone的扩展方法的启发,它依赖于构造函数。
进一步阅读:
https://tsherif.wordpress.com/2013/08/04/constructors-are-bad-for-javascript/
答案 0 :(得分:1)
1)这种行为本身只是重新引入构造函数带来的一些问题吗?
不,它正在重新引入构造函数。只需将initialize
换成constructor
即可,您的结果几乎相同。只有非常单一的语法: - )
2)我通过使用'选项扩展实例来违反开放/封闭原则。在initialize方法中?
不,这篇文章指出构造函数如何打破开放/封闭原则是为了将它们与另一个工厂交换出来,你必须在代码中删除new
(事实上你不这样做) 。但是如果你扩展你的课程,你就不必改变它的调用。
我对这种模式感觉不好,觉得我应该对消费者进行初始化控制。
好吧,如果你想这样做,只需删除初始化程序并让消费者执行extend
:
var x = _.extend(myFactory(), { name : 'shiny', type : 'alpha' });
var y = _.extend(myFactory(), { name : 'happy', type : 'beta' });