day21 闭包

一、 闭包概念

     能够读取其他函数内部变量的函数。只有函数内部的子函数才能读取局部变量,所以闭包可以理解成“定义在一个函数内部的函数“。在本质上,闭包是将函数内部和函数外部连接起来的桥梁。

1、闭包形式

function a(){
	function b(){
 		var bbb = 124;
		console.log(aaa);
	}
	var aaa = 123;
	return b; 
}
var glob = 100;
var demo = a();
demo();

   a函数里返回一个b函数,在外部定义一个demo接收,这样就把b函数保存在了外部。
在这里插入图片描述
当a函数执行完毕销毁执行期上下文,但这时候b已经保存在了外部,连带着b定义时a的AO和GO保存在了外部。所以当执行demo时,仍然能访问a的AO里的aaa。
在这里插入图片描述

2、下面这种形式,也是把b函数保存在了外部。

var demo;
function test(){
      var abc = 100;
      function b(){
             console.log(abc);
      }
      demo = b;
}
test();
demo();

3、如下函数,只有aAO定义了num, num每次自加,结果都会覆盖aAO里的num。

 function a(){
	var num = 100;
	function b(){
	       num ++;
	       function c(){
		      num ++;
		      console.log(num);
		}
		c();
	}
	 return b;                                                                     
}
var demo = a();
demo(); --> 102
demo(); --> 104

二、闭包作用

1、实现公有变量
例:函数累加器

function add(){
	var count = 0;
	function demo(){
		count ++;
		console.log(count);
	}
	return demo;
}
var counter = add();
counter();
counter();
function add(){
	var num = 0;
	function a(){
		console.log(++num);	
	}
	return a;
}
var myAdd = add();
myAdd();	
myAdd();
myAdd();

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](); --> 101
myArr[1](); --> 100

function eater(){
	var food = ""; --> 缓存结构
	var obj = {
		eat : function(){
			console.log("I am eating" + food);
		},
		push : function(myFood){
			food = myFood;
			console.log(food);
		}
	}
	return obj;
}
var eater1 = eater();
eater1.push("banana");
eater1.eat();

3、实现封装 属性私有化

function Deng(name,wife){
	var prepareWife = 'xiaozhang'; --> 私有化属性,无法直接访问
	this.name = name;
	this.wife = wife;
	this.divorce = function(){
		this.wife = prepareWife;	
	}
	this.changePrepareWife  = function(target){
		prepareWife = target;
	}
	this.sayPrepareWife = function (){
		console.log(prepareWife);
	}
}	
var deng = new Deng('deng',"xiaoliu");

4、模块化开发 闭包防止污染全局变量

变量私有化,不会污染全局变量,可以把特定的功能写到一个闭包里,然后返回一个接口用来启动。

var name = "123";
var init = (function (){ 
		var name = "ABC";
		function callName (){
			console.log(name);
		}
		return function (){
			callName();
		} //接口
}())
init();

把一个要在全局实现的功能放在局部里,防止污染全局变量

入口函数init
var initLee = (function (){
    var name = "456";
    function callName(){
    console.log(name);
    }
    return function(){
    	callName();
    }
}())
intLee();

三、闭包缺点:

当内部函数被保存到外部时,将会产生闭包。
闭包会导致原有的作用域链不释放,造成内存泄露。

四、闭包问题

function test(){
	var arr = [ ];
	for(var i = 0; i < 10; i ++){
		arr[i] = function(){
			document.write(i+' ');
		}//函数引用,未执行前,里面的i值不变
	}
	return arr; //返回一个含有10个函数的数组
}
var myArr = test();
for(var j = 0; j < 10; j ++){
	myArr[j](); --> 执行10个函数,找此时的i = 10
}

用立即执行函数解决 打印0-9

function test(){
	var arr = [ ];
	for(var i = 0; i < 10; i ++){
	    ( function(j){
		  // j = 0,1,2...	
		  arr[j] = function(){
			console.log(j);
		  }
	    }(i) );//返回10个立即执行函数
	}
	 return arr; 
}
var myArr = test();
for(var j = 0; j < 10; j ++){
 	myArr[j](); 
}

猜你喜欢

转载自blog.csdn.net/LGT970116/article/details/82990193