ES6之let原理+回调函数等待队列——五个完全相同的按钮,点第i个按钮弹出i
看此篇文章前,请确保已有闭包的知识储备~
一、问题引入
页面上五个完全相同的按钮,现在想实现点哪个按钮,哪个按钮就弹出自己是第几个。
<button>click me!</button>
<button>click me!</button>
<button>click me!</button>
<button>click me!</button>
<button>click me!</button>
乍一看,这不是很简单嘛,一个循环+一个绑定事件就搞定:
var btns = document.getElementsByTagName("button");
for (var = 0; i < btns.length; i++) {btns[i].onclick = function() { console.log(i);}
}
兴高采烈的点开按钮,你却发现每个按钮点出来都弹的是5
原来是因为:
一般单击按钮,都只能在循环结束后。
等到循环后再去单击按钮,调用的就是按钮上提前保存的事件处理函数
二、回调函数等待队列
这个时候我们就要了解一个概念,在程序执行中不仅有主程序,还有一个主程序之外的队列,回调函数等待队列
只有主程序中所有代码都执行完,才能从回调队列中取函数,进入主程序执行。
以上述问题作为例子,程序运行图如下:
主程序循环之后i=5,然后再去执行回调函数等待队列,故所有console.log输出结果都为5
三、解决方案
方法一:闭包函数
使用 匿名函数自调用,每次将传入的值i放在局部变量中,并使局部变量和onclick事件形成闭包,局部变量被永久保存起来。
此处闭包中函数不用返回到外部的原因:
按钮一直存在,属于全局定义,不用return
var btns = document.getElementsByTagName("button");for (var i = 0; i < btns.length; i++) {(function(i){ //循环几次,生成几个单独的闭包// var i; //如果有形参,相当于局部变量btns[i].onclick = function() { alert(i);}})(i);
}
console.log(i)
方法二:let
let在底层自动转换为匿名函数自调用,其实等效于方法一
当let碰上for:匿名函数自调擅自加工加入了循环变量,此处为i
var btns = document.getElementsByTagName("button");// let底层原理就是匿名函数自调,闭包
for (let i = 0; i < btns.length; i++) {// (function(i){ btns[i].onclick = function() { console.log(i);}// })(i);
}
ES6之let原理+回调函数等待队列——五个完全相同的按钮,点第i个按钮弹出i相关推荐
- 写一个函数,用户输入一个数判断是否是素数,并返弹出回值(又叫质数,只能被1和自身整数的数)
// 写一个函数,用户输入一个数判断是否是素数,并返弹出回值(又叫质数,只能被1和自身整数的数)function isPrime(num) {for (var i = 2; i < num; i ...
- Javascript第四章定义函数的形式、回调函数第五课
两者的区别: 第一种方法:函数声明在编写时可以先调用,再声明: 第二种方法:函数表达式必须先定义,再调用 更多免费教学文章请关注这里 函数的回调 主要的理解: 当用户用的时候,不是直接触发的状态,当他 ...
- 【黑马pink老师函数及应用作业】写一个函数,用户输入任意两个数字的最大值,并能弹出运算后的结果
<script>var num1 = prompt('请输入相比较的数值1');var num2 = prompt('请输入相比较的数值2');function num(num1,num2 ...
- C语言 回调函数 callback - C语言零基础入门教程
目录 一.回调函数原理 二.回调函数简介 1.函数指针 2.指针函数 3.回调函数解释 三.回调函数实战 四.回调函数使用总结 五.猜你喜欢 零基础 C/C++ 学习路线推荐 : C/C++ 学习目录 ...
- RTX5 | 消息队列04 - (实战技巧)串口中断回调函数ISR同步线程
文章目录 一.前言 二.实验目的 三.API 3.2.osMessageQueueGet 四.代码 4.1.main.h 4.2.stm32f1xx.it.c 4.3.main.c 五.Event R ...
- mysql 1539_MySQL:半同步(三)从库端初始化和回调函数
源码版本5.7.29 一.全局变量 semisync_slave_plugin.cc ReplSemiSyncSlave repl_semisync; /* indicate whether or n ...
- Opencv鼠标回调函数
1.目的 读取一张图片,在该图片上截取一个ROI区域,将截取的图像在新窗口显示,并可以保存至工程目录下. 2.实现环境 C++.VS2017.opencv 3.回调函数原理 回调函数就是一个通过函数指 ...
- 函数指针--Nginx和Redis中两种回调函数写法
1.Nginx和Redis中两种回调函数写法 #include <stdio.h>//仿Nginx风格 //结构外声明函数指针类型 typedef void (*ngx_connectio ...
- 菜鸟学习笔记:Java基础篇5(抽象类与接口、回调函数、内部类)
菜鸟学习笔记:Java面向对象篇下 抽象类 接口 回调函数 内部类 成员内部类 匿名内部类 抽象类 通过前面知识的学习,抽象类这个概念应该不难理解,但比较容易和后面要说的接口混淆,而且在面试中也比较爱 ...
最新文章
- PX4编写msg文件
- linux挂载到哪个分区,Linux中直接挂载硬盘和挂载分区有什么区别?
- ​常用的连续概率分布汇总
- C++ 虚函数表解析
- iOS 12 真机调试 Xcode 9 提示 Could not locate device support files.
- 鸿蒙系统海外名称,新商标表明华为鸿蒙系统在海外或叫做“Harmony OS”
- 【算法竞赛学习】二手车交易价格预测-Baseline
- 家用路由器及NAT协议
- 追光的人beta冲刺总结
- Getting Real ——把握现实
- 千万别把WIFI玩坏了!关于WIFI的新鲜玩法和商业模式探讨
- 2020年,微信的基地属性正在悄然转向
- 数据质量监控Griffin——使用
- Linux系统中 如何系统排错 二之文件引导阶段(引导文件丢失)!
- pip安装GeoIP时报fatal error: GeoIP.h: No such file or directory
- 要嫁就嫁程序员:那些你不理解的真实的他们。
- cacti mysql 修复_cacti数据库修复
- java毕业设计服装生产管理系统mybatis+源码+调试部署+系统+数据库+lw
- oracle层级计算推演,(特价书)Oracle 高性能SQL引擎剖析:SQL优化与调优机制详解(资深Oracle专家黄玮十年磨一剑,盖国强作序力荐)(china-pub首发)...
- Elitebook 735 更换键盘
热门文章
- [ES6] 细化ES6之 -- Class关键字
- 再见2019,拥抱2020
- 精确定位网页中各个元素的位置
- idea怎么导入jxl.jar库
- 汉堡王什么汉堡好吃_如何制作汉堡的汉堡胚?做汉堡胚需要注意什么?
- MyBatis复习(五):获取多表关联查询结果
- 狂野飙车9手游服务器维护,狂野飙车9_狂野飙车9公益服_变态版狂野飙车9_狂野飙车9官网_9917游戏...
- android picasso 三级缓存,Android中图片的三级缓存浅析
- php学习总结,PHP学习的技巧和学习的要素总结
- java纪元时间_Java实现纪元秒和本地日期时间互换的方法【经典实例】