我最近发现对JavaScript中的工厂功能模式很感兴趣。上课可能很干净,但是我发现他们有很多问题。 (我什至不打算谈论它们,因为这根本不是这个问题的目的。)
我尚不清楚工厂功能的一个主要方面。
如果我错了,请纠正我,但是在JavaScript类中,我的方法放置在结果对象的原型上,因此它们只能创建一次。这意味着类内部使用的构造函数不会将方法作为属性添加到每个新对象中,这从概念上讲意味着方法属于类而不是对象实例。
class Example {
constructor(message) {
this.message = message;
}
sayMessage() {
console.log(this.message);
}
}
let a = new Example("Hello!");
a.sayMessage(); // Outputs "Hello!"
console.log(Object.getOwnPropertyNames(a));
// Outputs ["message"]
Example.prototype.sayMessage = function() {
console.log(this.message + " Modified!");
};
let b = new Example("Hello!");
b.message = "Goodbye!";
b.sayMessage(); // Outputs "Goodbye! Modified!"
在上面的类中,sayMessage
对于该类的每个实例都是相同的函数。如所示,甚至可以稍后在原型上对其进行更改,从而更新该类的所有现有实例。我不能肯定地说我是否认为这是件好事,但这当然是有道理的。
但是,在工厂函数中,似乎返回的对象只是具有作为正常属性附加的所有必需方法。
function Example(message) {
let sayMessage = function() {
console.log(this.message);
};
return {
message: message,
sayMessage: sayMessage
};
}
let a = Example("Hello!");
a.sayMessage(); // Outputs "Hello!"
console.log(Object.getOwnPropertyNames(a));
// Outputs ["message", "sayMessage"]
// Modifying the prototype is pointless because
// we haven't explicitly placed any methods there
let b = Example("Hello!");
b.message = "Goodbye!";
b.sayMessage(); // Outputs "Goodbye!"
我想谈一点。因此,首先,首先要避免使用工厂功能这一点吗?为什么我们不创建一次函数,而是恢复为在每个实例之间复制它?
我喜欢这样的想法,当我使用工厂函数时,我可以更好地控制在最终对象中公开的内容,因为我可以在闭包中将事情保密,但是我仍然可以使用原型继承模型吗?或许还有一个更好的问题:我想吗?我发现反对工厂函数的主要论据之一是,在性能关键型应用程序中,它们比类慢。好吧,这不是部分原因吗?为每个新对象创建一整套方法听起来很浪费。听起来就像拥有原型的全部要点!
这里有很多问题。让我把它煮沸。我想听听不使用原型(或者相反地使用一个原型)的合理性,以及是否有一个兼顾两全其美的解决方案。
编辑:当我第一次发布问题时,我的第二个代码示例是使用Example
关键字创建new
实例,这是一个错字。