如果您定义该函数一次,并将该函数的引用传递给不同的变量/属性,那么是的,它会被存储一次。
var one_func = function () { console.log("I'm just one function."); };
var reused = one_func;
var reuser = { func : reused };
它们都具有指向同一函数的指针。
但如果你有这样的事情:
var Circle = function (r) {
var circle = {
radius : r,
calculate_area : function () { return 2 * Math.PI * r; }
};
return circle;
};
var circle_1 = Circle(2),
circle_2 = Circle(4);
这两个对象不共享calculate_area
.
您已经创建了该函数的两个不同版本。
由于函数范围和闭包,它们必须保持不同。
看,每个副本都知道自己的圈子r
.
如果你注意到的话,我不是在看circle.radius,而是在看r
传递到Circle
功能。
所以任何定义的函数inside of Circle
每次都必须是新的,因为这些函数保存对构造函数内部任何变量的引用,通过closure.
拥有多个副本所带来的内存消耗,与拥有完全私有属性所带来的好处相比,是非常值得的,直到你拥有成千上万的副本(除非我们谈论的是巨大的对象或可怕的旧浏览器,或者在 LED 上运行 JavaScript)烤面包机上的屏幕)。
更先进的引擎可能会优化这里的内存占用,但考虑到每个功能占用的内存很少,以及智能手机有多少 RAM(更不用说定制的游戏 PC),浪费 CPU 是不值得的。
EDIT
为了迂腐
var Wallet = function (opening_balance) {
var balance = opening_balance,
overdraft = 50,
is_sufficient_funds = function (amount) {
return balance + overdraft >= amount;
},
deposit = function (funds) {
if (amount <= 0) { return; }
balance += funds;
},
withdraw = function (amount) {
if (amount <= 0) { return; }
if (is_sufficient_funds(amount)) {
balance -= amount;
return amount;
}
},
public_interface = {
deposit : deposit,
withdraw : withdraw
};
return public_interface;
};
现在,很明显我们不希望balance
or overdraft
在任何情况下均可公开访问Wallet
.
即使是这个行人版本的钱包也相当安全。
当然,它现在没有做任何授权,所以你可以扣除一切,或者添加一百万美元......
...但是您可以将透支设置为 300 美元吗?
您可以手动复制值balance
?
即使你创造了var wallet = Wallet(35);
然后尝试重写deposit
方法,那么你重写它就绝对无法访问私有的balance
.
现在,这种内存开销与闭包相关的好处应该是显而易见的。
如果您愿意,您可以考虑多人游戏中枪支的射速。
或者角色的动作。
或者他们的健康。
或者高分。
通过将所有这些东西封装在闭包中,它们是不可调整的。
这并不意味着服务器是不可破解的。
但这确实意味着,在不从头开始重写引擎的情况下,人们可以进入的地方就少了。