我的用例如下:我想创建一个生产各种数据传输对象(DTO)的工厂。它们必须易于序列化,并且必须有一些额外的方法。
我当前的实现看起来像这样(simplified):
window.Dto = function(type, properties)
{
var
self = this,
values = {},
object = Object.create(self);
properties.forEach(function(prop){
Object.defineProperty(object, prop, {
get: function() { return values[prop]; },
set: function(value) { values[prop] = value; },
enumerable: true
});
});
this.getType = function()
{
return type;
};
this.doSomeMagic = function()
{
// ...
};
return object;
};
// creating a DTO of the Transport.Motorized.Car class
var carObject = new Dto("Transport.Motorized.Car", ["vendor", "model", "color", "vmax", "price"]);
(注意:我不想为这些对象中的每一个创建一个显式类,因为它们有很多,并且它们是从服务器端导出的。另外,你在上面看到properties
参数,实际上是具有验证约束等的元数据映射。)
我使用循环进行了快速性能检查,其中创建了50,000个此类对象。 performance.now()
告诉我它花了不少于1秒 - 看起来不错,但不太令人印象深刻。
我的问题主要是:工厂是否可以从自己的原型创建实例(如果我正确理解了代码的作用)并返回它?它有什么副作用?还有更好的方法吗?
答案 0 :(得分:2)
据我了解工厂功能,他们的全部内容不需要创建函数本身的新实例。相反,它只返回一个新创建的对象。
因此,我不是使用新创建的实例的实例属性(通过this
)(通过new
运算符),而是创建一个对象(让我们调用它{{1并且分配所有"实例"相反,该对象的方法。
然后,您可以使用factoryProto
作为新factoryProto
的{{1}}:
[[Prototype]]
如果您想从原型链中获得充分利润,可以在工厂函数之外定义object
。要跟踪window.Dto = function(type, properties) {
var factoryProto = {
getType: function() {
return type;
},
doSomeMagic: function() {
// ...
}
},
values = {},
object = Object.create(factoryProto);
properties.forEach(function(prop) {
Object.defineProperty(object, prop, {
get: function() { return values[prop]; },
set: function(value) { values[prop] = value; },
enumerable: true
});
});
return object;
};
// creating a DTO of the Transport.Motorized.Car class
var carObject = Dto("Transport.Motorized.Car", ["vendor", "model", "color", "vmax", "price"]);
,您可以将其添加为不可枚举的factoryProto
属性:
type