第一个例子
function a(){
function b(){
var bbb = 234;
document.write(aaa);
}
var aaa = 123;
return b;
}
var demo = a();
demo();
解析:但凡是内部的函数,被保存到了外部,就生成了闭包。a函数删除自己的aAO,但是b中仍然保存着aAO,所以仍然b仍然可以访问a的值。
第二个例子
function a(){
var num = 100;
function b(){
num ++;
console.log(num);
}
return b;
}
var demo = a();
demo();
demo();
分析:a执行完之后,b站在a的肩膀上,有了aAO,所以可以访问num值,第一次执行demo(),即执行一次b函数,num++,打印出101;第二次执行b函数,打印出了101++,即102.
第二次分析:b站在a的肩膀上,有了aAO,第一次b执行之后,销毁的是b的AO;并没有销毁基础aAO,所以是在101的基础上进行。
闭包
当内部函数被保存到外部时,将会生成闭包。闭包会导致原有作用域链不释放,造成内存泄露。
注意:内存泄露不是指安全性问题,而是指闭包的时候内存占用更多了,剩下的内存少了,看起来像内存泄露了一样。
闭包的作用
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]();
打印的结果是:101 100
原因:test函数执行,返回的是一个数组,里面的参数是a函数和b函数,接着a函数和b函数被调用,在test函数的AO下,所以先执行a函数num++变成101,随后同一个AO下,num–变成100.
闭包的例子
function eater(){
var food = '';
var obj = {
eat : function(){
console.log("i am eating "+ food);
food = '';
},
push : function(myFood){
food = myFood;
}
}
return obj; //注意要返回obj
}
var eater1 = eater();
eater1.push('apple');
eater1.eat();
立即执行函数
立即执行函数是针对初始化功能的函数,执行之后立刻被销毁,是匿名函数。即便是定义了函数的名字,也不起作用,即在外部调用的时候会发现函数未定义。
举例:
(function(a,b,c){
console.log(a + b + c);
}(1,2,3))
在上面的函数中,前面的括号中存放的是形式参数,后面的括号中存放的是实际参数。
- 同样,和正常的函数一样,他也有返回值。
var num = (function(a,b,c){
console.log(a + b + c);
}(1,2,3))
两种写法
- (function(){}()) //w3c推荐的写法
- (function(){})()
第二种写法的实例:
奇特的写法:只有表达式才能被执行符号执行
+ function test(){
console.log('a');
}();
上面的函数被执行,打印出的结果是a,并且会忽略函数的名字,比如说此时访问test,会报错。