匿名函数与闭包

匿名函数与闭包

匿名函数:

function(){return 'a'}

闭包:有权访问另一个作用域变量的函数(函数里的匿名函数),闭包不属于任何对象的属性和方法

闭包的作用:

1 返回局部变量:

function box(){
	var a=1;
	return function(){
		return a;
	}
}
console.log(box()())

2 将局部变量驻留在内存中:

function pox(){
	var age=1;
	age++;
	return age;
}
function box(){
	var age=1;
	return function(){
		age++;
		return age;
	}
}
console.log(pox());  //2
console.log(pox());  //2
console.log(box()());//2
console.log(box()());//2
var b=box();           //获得函数
console.log(b()) //2
console.log(b()) //3

PS:闭包里返回的局部变量不会被立即销毁回收,所以会占用更多的内存,过度使用会导致性能下降。

3 在循环里的匿名函数取得的变量都是最后一个:

例1:点击目标p节点,改变其属性

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>test</title>
	<script type="text/javascript" src="demo.js"></script>
</head>
<body>
	<p>1</p>
	<p>2</p>
	<p>3</p>
</body>
<script type="text/javascript">
function f(name){
	var e = document.getElementsByTagName(name)
	if(e){
		for(var i = 0;i < e.length;i++){            //或将var改成let
			e[i].onclick = function(){
				console.log(i)   //3
				e[i].style.color = 'red';   //e[i]改成this
			}
		}
	}
}
f('p');
</script>
</html>

或者改为:

<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
	<title>test</title>
	<script type="text/javascript" src="demo.js"></script>
</head>
<body>
	<p>1</p>
	<p>2</p>
	<p>3</p>
</body>
<script type="text/javascript">
function f(name){
	var e = document.getElementsByTagName(name)
	if(e){
		for(var i = 0;i < e.length;i++){    
			e[i].onclick = (function(i){
				return function(){       //返回匿名函数将变量驻留在内存中
					return e[i].style.color = 'red';  //此时a[i]可以改为this,this在这是e[i]
				}				
			})(i);//匿名函数自我执行
                        e[i]=null;//解除引用释放内存
                }
	}
}
f('p');
</script>
</html>

例2:

function box(){
	var arr=[];
	for(var i=0;i<5;i++){
		arr[i]=function(){
			return i; //匿名函数返回局部变量,此时是i的最终值
		}
	}
	return arr;
}
// 调用
for(var i=0;i<5;i++){
	document.write(box()[i]())
}
// 结果是:5个5,并不是0,1,2,3,4

改写:

改0:

function box(){
	var arr=[];
	for(var i=0;i<5;i++){
		arr[i]=i   //不用匿名函数,直接返回
	}
	return arr;
}
// 调用
for(var i=0;i<5;i++){
	document.write(box()[i])//1,2,3,4,5
}

改1:

function box(){
	var arr=[];
	for(var i=0;i<5;i++){
		arr[i]=(function(){   
			return i;
		})()//匿名函数自我执行
	}
	return arr;
}
// 调用
for(var i=0;i<5;i++){
	document.write(box()[i])//0,1,2,3,4
}

改2:常用

function box(){
	var arr=[];
	for(var i=0;i<5;i++){
		arr[i]=(function(num){   
			return function(){   //返回一个匿名函数,匿名函数会将变量驻留在内存中
				return num;
			}
		})(i)  //匿名函数自我执行
	}
	return arr;
}
// 调用
for(var i=0;i<5;i++){
	document.write(box()[i]())//0,1,2,3,4
}

4:关于this对象:
在匿名函数里的匿名函数使用this

例1:

var a=2;
var obj={
	a:1,
	run:function(){
		return function(){
			return this.a; //this这里指window
		}
	}
}
console.log(obj.run()()) //2 不是1

例2:

var a=2;
var obj={
	a:1,
	run:(function(){
		return function(){
			return this.a; //this这里指obj
		}
	})()
}
console.log(obj.run()) //1 不是2
// 其实obj.run()就是function(){return this.a}

更改this指向的两种方法:

例3:

var a=2;
var obj={
	a:1,
	run:function(){
		return function(){
			return this.a; 
		}
	}
}
console.log(obj.run().call(obj)	) //1 对象冒充

例4:

var a=2;
var obj={
	a:1,
	run:function(){
		var that=this;
		return function(){
			return that.a; 
		}
	}
}
console.log(obj.run()()) //1 传递this
PS:内存泄漏:匿名函数里得到的局部变量需要手动清理,上面的3中例1的改写方法用到的。

5:模仿块级作用域

for语句,if语句等其他循环语句没有单独的作用域,即没有封闭作用域的功能。

function box(){	
	(function(){
		for(var i=0;i<3;i++){
			console.log(i);  //此处会输出
		}		
	})()
	console.log(i); //此处会报错
}
box()

6 私有变量

function Box(value){
	var user = value;
	this.getUser = function(){
		return user;
	}
	this.setUser = function(value){
		user = value;
	}
}
var a = new Box('苏');
console.log(a.getUser());
var b = new Box('王');
console.log(b.getUser());
以上通过构造方法访问私有变量,但是对象的方法,在多次调用的时候会多次创建。

使用静态私有变量:

(function (){	
	var user=''              //变量初始化
	Box = function(value){   //构造方法,全局变量
		user = value;
	}; 
	Box.prototype.getUser = function(){
		return user;
	};
	Box.prototype.setUser = function(value){
	    user=value;
	}
})();
var box = new Box('苏');
console.log(box.getUser())

使用了prototype导致方法共享了,而user变成了静态属性(共享与不同对象的属性)。

7:模块模式:

1):对象字面量方式采用模块模式来创建

var box = function(){
	var age = 100;
	function run(){
		return 1;
	};
	return {             //直接返回对象
		go:function(){
			return age+run();
		}
	}
}();
console.log(box.go())

以上属于单例模式,永远保持对象的一个实例。

2):增强的模块模式:

function Box(){}
var desk=function(){
	var age=100;
	function run(){
		return 1;
	}
	var box=new Box();   //可以实例化的对象
	box.go=function(){
		return age+run();
	}
	return box;          //返回实例对象
}();
console.log(desk.go())




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值