我有一个看起来像这样的对象:
var myObj = {
_fooCon: function(f) {
if (typeof f != 'function') throw new TypeError('Bad Foo');
this.fn = f;
},
_barCon: function(f) {
if (typeof f != 'function') throw new TypeError('Bad Bar');
this.fn = f;
},
someFoo: function(v) {
return new this._fooCon(function(x) {
return x + ' Foo ' + v;
});
},
someBar: function(v) {
return new this._barCon(function(x) {
return x + ' Bar ' + v;
});
}
};
这样做的原因是我可以高效地使用 instanceof
(即,这样我就可以区分这两个对象,尽管它们结构相同,但它们在不同的场景中使用)。 (忽略 someFoo
和 someBar
相似的事实!)
有没有一种方法可以抽象构造函数,这样如果我需要创建,比如说,_bazCon
,我不需要重复自己;或者,如果存在错误,我不必修复每个构造函数定义?
我尝试创建一个工厂成员,如下所示:
_factory: function(type, f) {
if (typeof f != 'function') throw new TypeError('Bad ' + type);
this.fn = f;
}
...然后:
_fooCon: function(f) { return new this._factory('Foo', f); }
即使没有尝试过,我也知道这是行不通的!关于如何实现我想要的目标有什么想法吗?
最佳答案
如果您的函数确实做同样的事情,那么就这么简单:
var myObj = {
_factory: function(err) {
return function(f) {
if (typeof f != 'function') throw new TypeError('Bad ' + err);
this.fn = f;
};
},
someFoo: function(v) {
return new this._fooCon(function(x) {
return x + ' Foo ' + v;
});
},
someBar: function(v) {
return new this._barCon(function(x) {
return x + ' Bar ' + v;
});
}
};
myObj._fooCon = myObj._factory("Foo");
myObj._barCon = myObj._factory("Bar");
如果有其他行为可以区分它们,那么您可以让 _factory
接收在构造函数中调用的函数参数。该函数可以使用 .call
或 .apply
将 this
值设置为正在构造的对象。
另一种方法是使用构造函数来创建 myObj
,并利用变量作用域,这样您就不需要公开 _xxxCon
构造函数。
这使用匿名函数作为构造函数,因为我们不再需要它。
var myObj = new function() {
var _factory = function(err) {
return function(f) {
if (typeof f != 'function') throw new TypeError('Bad ' + err);
this.fn = f;
};
};
var _fooCon = _factory("Foo");
var _barCon = _factory("Bar");
this.someFoo = function(v) {
return new _fooCon(function(x) {
return x + ' Foo ' + v;
});
},
this.someBar = function(v) {
return new _barCon(function(x) {
return x + ' Bar ' + v;
});
}
};
您不一定需要将外部函数用作构造函数,但您确实需要一个将对象返回到 myObj
的函数。
如果您确实想要公开_xxxCon
函数,则将var
更改为this.
,然后将this.
回到 someFoo
和 someBar
.
关于JavaScript DRY 对象构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14417463/