本文通过Firefox Firebug控制台测试,对比了循环内动态定义的函数与循环外引用函数的内存表现。结果显示,每次循环重新定义函数会创建独立对象并占用额外内存,而引用同一函数则共享内存。建议在不依赖循环变量变化的场景下,将函数定义移至循环外以优化性能。
JavaScript函数引用与内存开销分析
以下代码展示了函数定义与引用的具体实现:
代码片段如下:
var arr = [];
var cc = function(){alert('xx');};
for(var i = 0; i<2; i++){
arr[i] = function(){alert('yy');}
arr[i+10] = cc;
}
console.group('开始')
console.group('1')
console.info( arr[0] == arr[1]);
console.info( arr[0] === arr[1]);
console.info( arr[0].toString());
console.info( arr[1].toString());
console.groupEnd('1')
console.group('2')
console.info( arr[10] == arr[11]);
console.info( arr[10] === arr[11]);
console.info( arr[10].toString());
console.info( arr[11].toString());
console.group()
console.groupEnd('开始'); 在Firefox浏览器的Firebug控制台中运行上述代码,结果如图所示:

分析:
当第五行的循环执行完毕后,arr数组的内容如下:
arr[0] = function(){ alert('yy'); }
arr[1] = function(){ alert('yy'); }
arr[10] = cc
arr[11] = cc
通过控制台输出的结果(见上图)可以观察到:
arr[0] 与 arr[1] 不相等(== 为 false)。
然而 arr[10] 与 arr[11] 相等,因为它们引用的是同一个预先定义的变量 cc。
在循环过程中,每次迭代都会重新定义一个新的函数 function(){alert('yy');}。
尽管 arr[0] 和 arr[1] 的 toString() 输出内容相同,但它们是两个独立的方法对象,各自占用独立的内存空间。因此,为了节省内存,可以考虑将此类函数定义在循环外部。
将函数定义在循环外部的必要前提是:该函数内部不使用在循环中发生变化的变量。