作用域、立即执行函数:
AO:Activation Object , GO: Global Object
function a() {
function b() {
var bb = 234;
aa = 0;
}
var aa = 123;
b();
console.log(aa);
}
var glob = 100;
a();
// GO: glob:undefined, 100,
// a:f a(){},
// b:f b() {},
// aa:undefined,123,0,
// AO: bb:undefined,234,
// 输出:
// 0
function a() {
var num = 100;
function b() {
num++;
console.log(num);
}
return b;
}
var demo = a();
demo();
demo();
// GO: a : f a(){},
// demo : undefined, f b(){},101,102
// AO: num:undefined,100,
// b:f b(){},
// 输出:
// 101
// 102
立即执行函数:
例如:执行完即销毁,再也找不到abc();
(function abc() {
var a = 123;
var b = 234;
console.log(a + b);
}())
(function abc(a, b, c) {
console.log(a + b + c);
}(1, 2, 3))
var num = (function abc(a, b, c) {
var d = a + b + c;
return d;
}(1, 2, 3))
console.log(num);
写法有几种?
(function () {}()); //W3C建议使用;
(function () {})();
var test = function () {}(); //test将找不到了..
+ function test() {}(); // + | - | ! test()将找不到..
注意:
function test(a) {
console.log(a);
}()
// 报错
function test(a, b, c, d) {
console.log(a + b + c + d);
}(1, 2, 3, 4)
// 不执行
闭包:
内部函数保存到了外部,就会生成闭包。闭包会导致原有作用域链不释放,造成内存泄漏。
- 实现公有变量
- 可以做缓存
- 可以实现封装,属性私有化
- 模块化开发,防止污染全局变量
例1.先执行 var demo = a(); 得到aaa = 123;并把函数function b() {}抛给demo;再执行demo(); bbb=234;
function a() {
function b() {
var bbb = 234;
console.log(aaa);
}
var aaa = 123;
return b;
}
var glob = 100;
var demo = a();
demo();
// GO: a: f a() {}
// glob: undefined,100
// demo: undefined,bbb:234,
// AO:b:f b(){},
// aaa:undefined,123
// bbb:undefined,234
// 输出:
// 123,
例2.
function test() {
var num = 100;
function a() {
num++;
console.log(num);
}
function b() {
num--;
console.log(num);
}
return [a, b];
}
var myArr = test();
myArr[0]();
myArr[1]();
// GO: test : f test() {},
// myArr: undefined,[f a(){},f b(){}]
// AO: num: undefined ,100,101,100
// a: f a(){},
// b: f b(){},
// 输出:
// 101,
// 100
例3.
function eater() {
var food = "";
var obj = {
eat: function () {
console.log("I am eating " + food);
food = "";
},
push: function (myFood) {
food = myFood;
}
}
return obj;
}
var eater1 = eater();
eater1.push('banana');
eater1.eat();
// GO: eater: f eater() {},
// eater1: undefined, {
// eat: f() {},
// push: f(myFood) {}
// }
// AO: food: undefined, "", banana,
// obj: undefined, {
// eat: f() {},
// push: f(myFood) {}
// }
// 输出:
// I am eating banana
例4. 因为i最后为10,arr[i] = function () {console.log(i);} 中的
function () {console.log(i);}要在 return arr;后的 myArr (j)(); 才执行,
所以最后执行console.log(i); 全都是10.
function test() {
var arr = [];
for (var i = 0; i < 10; i++) {
arr[i] = function () {
console.log(i);
}
}
return arr;
}
var myArr = test();
for (var j = 0; j < 10; j++) {
myArr[j]();
}
// GO: test : f test(){},
// myArr : undefined,[arr[0] f(){},...],
// j : 0,1...10
// AO: arr : undefined,[arr[0] f(){},...],
// i : 0,1...10,
// 输出:(十个10)
// 10
// 10
// 10...
例5. 修改例4;
function test() {
var arr = [];
for (var i = 0; i < 10; i++) {
(function (j) {
arr[j] = function () {
console.log(j);
}
}(i));
}
return arr;
}
var myArr = test();
for (var j = 0; j < 10; j++) {
myArr[j]();
}
// GO: test : f test(){},
// myArr : undefined,[arr[0] f(){},...],
// j : 0,1...10
// AO: arr : undefined,[arr[0] f(){},...],
// i : 0,1...10,
// 输出:
// 1,2,3,4,5,...9