回答你剩下的问题:“没有构造函数的迂回方式是什么?”
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,还是将它们构建为私有作用域中的函数声明,或者将它们直接放入 areturn { func1 : () {...},... };
中都无关紧要,只要它们在调用时在该函数内部定义(即:不是在原型链上——无论如何,你不能在这个模式中使用它——你不会用new调用这个函数。
好的,这一切都很好。你现在有了一个工作的钱包制造商(没有安全性和用户功能,yadda-yadda ... ...家庭作业)。
但是,如果您想向其中添加PRIVATE STATIC成员怎么办?如果您需要跟踪序列号以便向人们发行银行卡怎么办?或者您需要跟踪分支编号?这就是布赖恩的 IIFE 发挥作用的地方。除了返回钱包 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;
}());
现在你有了静态属性(在最外层的闭包中,钱包工厂可以永久访问,作为“静态”成员),并且你有基于实例的私有成员,它是在创建过程中添加的内部方法实例对象,将具有完全访问权限。
唯一的缺点是:
失去这个特定类的原型能力,因为您没有使用构造函数。嗯。如果您的对象需要此设置,那么不值得拥有它
......如果他们不需要,并且公共一切都很酷,那么只需使用构造函数和原型 - 或者只是构建内联对象,没有方法,并构建服务(函数)以对每个类似构建的对象进行操作。
如果您以这种方式构建所有对象,那么当您创建数千个或数万个这样的对象时,您将遭受内存损失,每个对象都有自己的函数副本(以包含私有引用)。同样,这是您为功能支付的价格。在必须使用安全/干净接口的地方进行内存打击,在不需要的地方不要这样做。
也不言而喻,但避免在金融机构中使用它,因为面向客户的代码并不是信任添加和删除真实货币的最佳场所......
希望这能说明问题。