回答你剩下的问题:“没有构造函数的迂回方式是什么?”
Brian 的想法是正确的 - 但他真正创建的是具有私有属性的单一对象,而不是工厂。
因此,为此,如果您想要一个函数,它为“类”的每个实例授予其私有属性的唯一副本,您可以这样做(我将说明一个实际的类,它比“Foo”和“Bar”,以更好地说明概念 - 将其重新组合成您的预期用途应该非常简单):
var makeWallet = function (starting_amount) {
var amount = starting_amount,
overdraft = 1000,
addAmount = function (added_funds) { amount += added_funds; },
deductAmount = function (extracted_amound) {
if (is_sufficient_funds(amount, overdraft, extracted_amount)) {
amount -= extracted_amount;
return makeWallet(extracted_amount);
}
},
// other needed public/helper methods here...
// checkBalance(), is_sufficient_funds(), etc...
public_interface = {
// add all public-API methods you need here
addFunds : addAmount,
deductFunds : deductAmount
};
return public_interface;
};
现在,您有了一个返回对象的函数。每个对象都有访问该对象自己的“私有”(即:封闭)amount 变量的方法,该变量对于这些方法是唯一的,并且只能由这些方法访问。
无论您将函数构建为私有作用域中的 var,还是将它们构建为私有作用域中的函数声明,或者将它们直接放入 return { func1 : () {...},... }; 中,都无关紧要,只要它们是在该函数内部定义的它被调用(即:不在原型链上——无论如何你不能在这个模式中使用它——你会NOT用新)。
好的,一切都很好。你现在有了一个可以工作的钱包制造商(没有安全性和用户功能,yadda-yadda ... ...家庭作业)。
但是,如果您想向其中添加 PRIVATE STATIC 成员怎么办?
如果您需要跟踪序列号,以便向人们发行银行卡,该怎么办?或者您需要跟踪分支编号?这就是布赖恩的 IIFE 发挥作用的地方。除了返回完成的钱包对象之外,它将返回 wallet FACTORY。
var makeWallet = (function () {
var serial_num = 0,
branch_num = "A011002z";
function walletMaker = function (starting_amount) {
/*same function as before, except that you ALSO call:
serial_num += 1; in the construction of the wallet, and assign the id */
var id = serial_num += 1;
return wallet;
}
// then you return the wallet-factory
// which becomes the new value of the outer function
return walletMaker;
}());
现在你已经有了静态属性(在最外面的闭包中,钱包工厂将作为“静态”成员永久访问),AND你具有基于实例的私有成员,在创建实例对象期间添加的内部方法将可以完全访问这些成员。
唯一的缺点是:
失去此特定类的原型能力,因为您没有使用构造函数。嗯。如果您的对象需要此设置,那么不值得拥有它...
...如果他们不这样做,并且 public-everything 很酷,那么只需使用构造函数和原型 - 或者只是构建内联对象,没有方法,并构建服务(函数)以对每个类似构建的对象进行操作.
如果您以这种方式构建所有对象,那么当您创建数千个或数万个这样的对象时,您将遭受内存损失,每个对象都有自己的函数副本(将私人参考)。同样,这是您为功能支付的价格。在必须使用安全/干净接口的地方进行内存打击,在不需要的地方不要这样做。
也不言而喻,但要避免在金融机构中使用它,因为面向客户的代码并不是信任添加和删除真钱的最佳场所...
希望能解决问题。