闭包
当内部函数被保存到外部时,将会生成闭包。闭包会导致原有作用域链不释放,造成内存泄露。
闭包的作用
实现公有变量(eg.实现函数计数器)
function test(){ var number = 0; function demo(){ number++; console.log(number); } return demo; } var counter=test(); counter(); counter(); counter();
可以做缓存(存储结构)
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]();
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"); eater.eat();
- 可以实现封装,属性私有化(未学)
- 模块化开发,防止污染全局变量(未学)
闭包
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](); //十个10
}
执行的时候,值是什么才有用,函数声明的时候那个值没有意义。(这句话可能不对,但是放在这里便于理解。)
立即执行函数
定义:此类函数没有声明,在一次执行过后即释放。适合做初始化工作。
var num = (function(a,b,c){
//函数体
var num=a+b+c;
return num;
}(1,2,3))
console.log(num); //6
这个函数无需命名。可以有参数,可以有返回值
!这个语法是发现的,就是()的作用,不是定义的新功能
(function (){
//函数体
}());
//两种都对,但是上面是W3C推荐的
(funtion (){
//函数体
})();
下面看一下到底为啥这种写法可以达成立即执行函数:
只有表达式才能被执行。
被执行符号执行的表达式,会忽略表达式名。
():是执行符号,也是一种运算符。
一旦表达式被()执行,就会失去函数的索引
var demo = function(){
console.log("4545");
}();
console.log(typeof demo); //undefined
闭包的防范
//这里想要把上面的输出 十个10的闭包改写成输出0-9
//问题其实在于,闭包形成的函数的作用域链,类似一对十
//就是说,test的AO被那10个函数共用
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 k = 0; k < 10; k++) {
myArr[k](); //十个10
}
//用立即执行函数
//循环10次,执行10个不同的立即执行函数(就不会去找test()函数里面去找 i )
//每个arr[]函数 在10个不同的立即执行函数里面找 i 就能找到 0-9 了