例子1
- 立即调用表达式会立即执行,不需要test()调用
- 显示调用test()只是会调用一个匿名函数
- 局部变量i不会随着调用的结束而被回收,而是一直保存在内存中
javascript
var test = (function () {
console.log("test func");
var i = 0;
return function () {
console.log(i);
return i++;
}
})();
console.log("........");
test(); //0
test(); //1
test(); //2
// output
// test func
// ........
// 0
// 1
// 2
例子2
- test不是立即调用的,需要显示调用test()返回匿名函数的引用,如:var a = test(),这时a指向匿名函数
- a()调用这个匿名函数,局部变量i对于a来说一直会常驻内存中
- var b = test(),再次调用test,b会返回一个新的匿名函数的拷贝,并且i对于b也是唯一的
javascript
var test = function () {
console.log("test func");
var i = 0;
return function () {
console.log(i);
return i++;
}
};
console.log("........");
var a = test();
a(); //0
a(); //1
a(); //2
var b = test()
b(); //0
// output
// ........
// test func
// 0
// 1
// 2
// test func
// 0
例子3
javascript
var arr = [1, 2, 3];
var obj = {};
var test = function () {
for (var i=0; i<arr.length; i++) {
obj[i] = function () {
console.log(i);
};
}
}
test();
var fn0 = obj[0];
var fn1 = obj[1];
var fn2 = obj[2];
fn0(); //3
fn1(); //3
fn2(); //3
- 在for循环里创建了一个立即调用函数表达式
- fn0,fn1,fn2分别指向了匿名函数的引用
- fn0(),fn1(),fn2()都访问了i(这个i是位于这个匿名函数的上层作用域链,它会被保存在内存中,对于每一个函数引用来说i是唯一的)
javascript
var arr = [1, 2, 3];
var obj = {};
var test = function () {
for (var i=0; i<arr.length; i++) {
(function (i) {
obj[i] = function () {
console.log(i);
};
})(i); //i作为参数传给立即调用函数
}
};
test();
var fn0 = obj[0];
var fn1 = obj[1];
var fn2 = obj[2];
fn0(); //0
fn1(); //1
fn2(); //2
javascript
var arr = [1, 2, 3];
var obj = {};
var test = function () {
for (var i=0; i<arr.length; i++) {
(function (i) {
obj[i] = function () {
console.log(i++);
};
})(i); //i作为参数传给立即调用函数
}
};
test();
var fn0 = obj[0];
var fn1 = obj[1];
var fn2 = obj[2];
// 两次fn0()访问同一个内存中的i值
fn0(); //0
fn0(); //1
// 两次fn1()访问同一个内存中的i值
fn1(); //1
fn1(); //2
// 两次fn2()访问同一个内存中的i值
fn2(); //2
fn2(); //3
例子4
javascript
var arr = [1, 2, 3];
// 用来存放函数的数组
var fns = [];
var add = function () {
for (var i = 0; i < arr.length; i++) {
(function (i) {
// 把匿名函数push到fns中
fns.push(function () {
// 由于函数引用了上层作用域链的i,当被调用时i值不会被改变
console.log(arr[i]);
});
})(i);
}
};
// 遍历fns执行数组中的函数
var start = function () {
for (var i = 0; i < fns.length; i++) {
// 执行fns中的匿名函数
fns[i]();
}
};
add();
start();
// output
// 1
// 2
// 3