闭包的概念以及认识闭包

目录

一、什么是闭包

二、演示闭包可以实现的效果

三、闭包的案例

四、定时器执行的过程

五、通过使用闭包创建一个更灵活的函数

六、有效读取并区分当前是否存在闭包练习


闭包是一个很神奇的东西,之前用的时候总是感觉懵懵懂懂不得其精髓,最近利用一些空闲时间研究了下闭包,现在将这段时间总结的一些案例和概念整理整理吧。

一、什么是闭包

闭包:在一个作用域中可以访问另一个作用域的变量或者函数

如下:

<script>
 // 1
	 // 闭包:在一个作用域中可以访问另一个作用域的变量或者函数
	
	 // 未发生闭包
	 function fn(){
	 	var n = 10;
	 	return n
	 }
	
	 fn(); // 输出10
	
	 // 好处/特点:延展了函数的作用域范围
	 function fn(){
	 	var n = 10;
	 	return function (){
	 		return n
	 	}
	 }
	
	 var f = fn()
	
	 console.log(f()) // 输出10,通过访问父级作用域获得数据
	
</script>

二、演示闭包可以实现的效果

<script>
 // 2
	function getFun(n){
		return function(m){
			return n + m
		}
	}
	// 求100 + m
	var fn100 = getFun(100)
	// 求1000 + m
	var fn1000 = getFun(1000)
	
	console.log(fn100(1)) 		// 输出 101
							
	console.log(fn1000(1))		// 输出1001
	
</script>

三、闭包的案例

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
        <ul id="heroes">
		    <li>安其拉</li>
		    <li>礼拜</li>
		    <li>诸葛亮</li>
		    <li>狄仁杰</li>
	    </ul>
	</body>
</html>

<script>
 // 3

	// 方式1:给li注册点击事件(对象的自定义属性)
	var heroes = document.getElementById('heroes');
	var list  = heroes.children;
	for(var i = 0; i < list.length; i++) {
		var li = list[i];
		li.index = i
		li.onclick = function (){
			// 点击li的时候输出当前li的索引
			console.log(this.index)
		}
	}
	
	
	// 方式2:使用闭包的方式 
	// 问题:延展了作用域但降低了性能
	var heroes = document.getElementById('heroes');
	var list  = heroes.children;
	for(var i = 0; i < list.length; i++) {
		var li = list[i];
		
		(function (i){
			li.onclick = function (){
				// 点击li的时候输出当前li的索引
				console.log(i)
			}
		})(i)
	}
	
</script>

四、定时器执行的过程

        setTimeout的工作就是把第一个参数放到任务队列上来
        当执行代码的进程已将执行栈上的代码全部执行完后才会通过消息循环 取出任务队列要执行的代码依次执行

五、通过使用闭包创建一个更灵活的函数

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<body>
        我是字体的演示
        <button id="btn1" size="12">按钮1</button>
		<button id="btn2" size="14">按钮2</button>
	    <button id="btn3" size="16">按钮3</button>
	</body>
</html>

<script>
 // 5案例
	var btn1 = document.getElementById('btn1');
	var btn2 = document.getElementById('btn2');
	var btn3 = document.getElementById('btn3');
	
	btn1.onclick = function(){
		document.body.style.fontSize = '12px';
	}
	
	btn2.onclick = function(){
		document.body.style.fontSize = '14px';
	}
	
	btn3.onclick = function(){
		document.body.style.fontSize = '16px';
	}
	
	// 闭包方式 创建一个更灵活的函数
	function makeFun(size){
		return function(){
			document.body.style.fontSize = size + 'px';
		}
	}
	
	btn1.onclick = makeFun(12)
	btn2.onclick = makeFun(14)
	btn3.onclick = makeFun(16)
	
	// 拓展
	function makeFun(size){
		return function(){
			document.body.style.fontSize = size + 'px';
		}
	}
	var box = document.getElementById('box');
	var buttons = box.children;
	
	for(var i = 0; i<buttons.length;i++){
		var btn = buttons[i];
		
		// 获取标签自定义的属性
		var size = btn.getAttribute('size')
		btn.onclick = makeFun(size);
	}
</script>

六、有效读取并区分当前是否存在闭包练习

<script>
 // 6案例
	var name  = 'The Window';
	var object = {
		name:'My Object',
		getNameFunc: function(){
			console.log(this,'-p--p-p-p-p-p-p-p-pp-p-')	// 此处this指向object对象	
			return function (){
				console.log(this,'-----ooooo-----') // 此处this指向全局作用域Window
				return this.name;
			}
		}
	}
    // 由于是在全局作用域下直接调用getNameFunc()()  
	console.log(object.getNameFunc()()); // 输出:The Window 
	
    // 此处和以上console同理
	var fn = object.getNameFunc() 
	fn()		// 此为全局作用域下调用 
	
	var name  = 'The Window';
	var object = {
		name:'My Object',
		getNameFunc: function(){
			var that = this;
			return function (){
                // 此处that指向object对象
				console.log(that,'-p--p-p-p-p-p-p-p-pp-p-')	
				return that.name;
			}
		}
	}
	console.log(object.getNameFunc()()); 		// 输出:My Object
</script>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

普通前端

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值