编写高性能JavaScript(译)(2)
接下来,我们谈谈函数。正如我们已经说过,垃圾收集的工作原理,是通过回收不再是访问的内存块(对象)。为了更好地说明这一点,这里有一些例子。
function foo() {
var bar = new LargeObject();
bar.someCall();
}
当foo返回时,bar指向的对象将会被垃圾收集器自动回收,因为它已没有任何存在的引用了。
对比一下:
function foo() {
var bar = new LargeObject();
bar.someCall();
return bar;
}
// somewhere else
var b = foo();
现在我们有一个引用指向bar对象,这样bar对象的生存周期就从foo的调用一直持续到调用者指定别的变量b(或b超出范围)。
闭包(CLOSURES)
当你看到一个函数,返回一个内部函数,该内部函数将获得范围外的访问权,即使在外部函数执行之后。这是一个基本的闭包 —— 可以在特定的上下文中设置的变量的表达式。例如:
function sum (x) {
function sumIt(y) {
return x + y;
};
return sumIt;
}
// Usage
var sumA = sum(4);
var sumB = sumA(3);
console.log(sumB); // Returns 7
在sum调用上下文中生成的函数对象(sumIt)是无法被回收的,它被全局变量(sumA)所引用,并且可以通过sumA(n)调用。
让我们来看看另外一个例子,这里我们可以访问变量largeStr吗?
var a = function () {
var largeStr = new Array(1000000).join('x');
return function () {
return largeStr;
};
}();
是的,我们可以通过a()访问largeStr,所以它没有被回收。下面这个呢?
var a = function () {
var smallStr = 'x';
var largeStr = new Array(1000000).join('x');
return function (n) {
return smallStr;
};
}();
我们不能再访问largeStr了,它已经是垃圾回收候选人了。【译者注:因为largeStr已不存在外部引用了】






