JavaScript闭包 循环输出i
html
<body>
<p>产品一</p>
<p>产品二</p>
<p>产品三</p>
<p>产品四</p>
<p>产品五</p>
</body>
js
function init() {
var pAry = document.getElementsByTagName("p");
for( var i=0; i<pAry.length; i++ ) {
pAry[i].onclick = function() {
alert(i);
}
}
}
window.onload = init;
上面代码点击每个p,输出都是5,因为这里的 i 是个引用。演示地址
要想输出对应的i,有以下方法:
1、将变量 i 保存给在每个段落对象(p)上
function init() {
var pAry = document.getElementsByTagName("p");
for (var i = 0; i < pAry.length; i++) {
pAry[i].i = i;
pAry[i].onclick = function() {
alert(this.i);
}
}
}
window.onload = init;
2、将变量 i 保存在匿名函数自身
function init() {
var pAry = document.getElementsByTagName("p");
for (var i = 0; i < pAry.length; i++) {
(pAry[i].onclick = function() {
alert(arguments.callee.i);
}).i = i;
}
}
window.onload = init;
caller返回一个函数的引用,这个函数调用了当前的函数;
callee返回正在执行的函数本身的引用,它是arguments的一个属性
3.加一层闭包,i以函数参数形式传递给内层函数
function init() {
var pAry = document.getElementsByTagName("p");
for (var i = 0; i < pAry.length; i++) {
(function(arg) {
pAry[i].onclick = function() {
alert(arg);
};
})(i); //调用时参数
}
}
window.onload = init;
4、加一层闭包,i以局部变量形式传递给内存函数
function init() {
var pAry = document.getElementsByTagName("p");
for (var i = 0; i < pAry.length; i++) {
(function() {
var temp = i; //调用时局部变量
pAry[i].onclick = function() {
alert(temp);
}
})();
}
}
window.onload = init;
5、加一层闭包,返回一个函数作为响应事件(注意与3的细微区别)
function init() {
var pAry = document.getElementsByTagName("p");
for (var i = 0; i < pAry.length; i++) {
pAry[i].onclick = function(arg) {
return function() { //返回一个函数
alert(arg);
}
}(i);
}
}
window.onload = init;
6、用Function实现,实际上每产生一个函数实例就会产生一个闭包
function init() {
var pAry = document.getElementsByTagName("p");
for (var i = 0; i < pAry.length; i++) {
pAry[i].onclick = new Function("alert(" + i + ");"); //new一次就产生一个函数实例
}
}
window.onload = init;
7、用Function实现,注意与6的区别
function init() {
var pAry = document.getElementsByTagName("p");
for (var i = 0; i < pAry.length; i++) {
pAry[i].onclick = Function('alert(' + i + ')')
}
}
window.onload = init;
看了这篇文章,又想到用es5,es6的两个方法:
8、用es5 forEach函数
这里用forEach也行成了一个所谓的闭包,forEach里的执行函数也行成了一个闭包,每个执行体里,index都是一局部作用域,那为什么用Array.from呢,我们也可以用[].slice.call(node)我们类数组对象转化成真正的数组
function init() {
var pAry = document.getElementsByTagName("p");
//pAry = Array.from(pAry);
pAry = Array.prototype.slice.call(pAry);
pAry.forEach(function(currentItem,index){
currentItem.onclick = function(){
alert(index);
}
})
}
window.onload = init;
9、用es6的let声明块级变量
function init() {
var pAry = document.getElementsByTagName("p");
for( let i=0; i<pAry.length; i++ ) {
pAry[i].onclick = function() {
alert(i);
}
}
}
window.onload = init;
知乎关于这个问题也有一些回答
https://www.zhihu.com/question/33468703
JavaScript闭包 循环输出i的更多相关文章
- JavaScript利用闭包循环绑定事件
我们经常在做前端面试题的时候,会遇到循环绑定事件后,输出打印结果,很多人总是搞不清楚,今天借此机会跟大家梳理一下闭包相关作用. 1.首先我们举一个简单的例子. html部分: <a href=& ...
- 从javascript的循环问题来看待闭包本质
第一次接触这个问题还是在我刚开始学js的时候,当时就是一头雾水,时隔一年多了,突然又想起了这个问题,在这个春气盎然的周末,我就坐下来研究下并把结果和大家分享下: 先看代码:demo.html < ...
- JavaScript学习笔记-循环输出菱形,并可菱形自定义大小
var Cen = 6;//定义菱形中部为第几行(起始值为0) //for循环输出菱形 document.write("<button onclick='xh()'>点我for循 ...
- JavaScript闭包深入解析
for (var i=1; i<=5; i++) { setTimeout( function timer() { console.log( i ); }, i*1000 ); } --上面这段 ...
- JavaScript 闭包系列二(匿名函数及函数的闭包)
一. 匿名函数 1. 函数的定义,可分为三种 1) 函数声明方式 function double(x) { return 2*x; } 2)Function构造函数,把参数列表和函数体都作为字 ...
- JavaScript闭包模型
JavaScript闭包模型 ----- [原创翻译]2016-09-01 09:32:22 < 一> 闭包并不神秘 本文利用JavaScript代码来阐述闭包,目的是为了使普通 ...
- JavaScript 闭包整合
初遇闭包感觉很困惑,上网查看了些许介绍,有很多没看懂,就想先对能懂的东西整整 首先觉得要了解闭包,要先对一.JavaScript的变量作用域和作用域链有基本了解 1.变量的作用域分为:全局变量和局部变 ...
- JavaScript ——闭包理解
昨天晚上听别人谈起闭包这个东西,虽然对js有一点了解但却丝毫没有印象,今天也没什么事就顺便研究了一下满足好奇宝宝.整合于网上的理解,记录一下. 一.闭包的作用域 要理解闭包,首先必须理解Javascr ...
- Javascript闭包的一些研究
原文:Javascript闭包的一些研究 本文不谈闭包的概念,因为概念容易把人搞晕,本文希望通过几个鲜活的例子来探究闭包的性质,相信对理解闭包会有所帮助. 程序1 var f = (function( ...
随机推荐
- C语言实例解析精粹学习笔记——44(冒泡排序)
冒泡排序,从序列的最后一个元素与前一个元素比较大小,如果R[n-1]>R[n]则交换两个元素的位置(R[0]作为临时存放区)将最小的数据交换到R[1],第二次循环将第二小的数交换到R[2].通过 ...
- [BZOJ1208]宠物收养所(Splay)
Description 最近,阿Q开了一间宠物收养所.收养所提供两种服务:收养被主人遗弃的宠物和让新的主人领养这些宠物.每个领养者都希望领养到自己满意的宠物,阿Q根据领养者的要求通过他自己发明的一个特 ...
- 【File】文件操作(初识文件操作一)
一,初识文件流 看到标题就知道接下来的所有操作对象都是面对文件进行的.那么问题来了.在java中目录是不是也属于文件呢?答案是yes.既然目录也属于文件,那么对于目录跟文件的区分就显现出来了.在接下来 ...
- java集群技术
序言 越来越多的关键应用运行在J2EE(Java 2, Enterprise Edition)中,这些诸如银行系统和账单处理系统需要高的可用性(High Availability, HA),同时像Go ...
- .net core 项目加载提示项目文件不完整缺少预期导入的解决办法
今天把在远端的仓库的代码在另一台电脑上拷贝下来,电脑上.net core 环境也已经安装了,但是发现有几个项目没有加载成功,然后重新加载项目,vs2017却提示 项目文件不完整,缺少预期导入 查看错误 ...
- 62、在app遇到全局异常时避免直接退出,如何让app接管异常处理?
1.创建一个类为CrashHandler import android.content.Context; import android.os.Looper; import android.util.L ...
- 【word ladder】cpp
题目: Given two words (beginWord and endWord), and a dictionary, find the length of shortest transform ...
- chrome浏览器设置自动切换代理上网的方法
利用shadowsocks代理软件实现FQ时,如果都走代理模式,流量肯定不够.可以利用chrome的SwitchyOmega插件实现自动根据URL来决定是否使用代理.设置如下: 1.安装Switchy ...
- php伪随机数漏洞 以及脚本php_mt_seed的使用教程
前几天在群里看到了一个题目,发现自己没有接触过这个伪随机数这个漏洞,在此记录下. 搜索这两个函数 mt_scrand() mt_rand() mt_scrand(seed)这个函数的意思,是通过分发s ...
- python week09 Mysql 数据库基础知识
第一篇:初识数据库 注:<基础概念,不再赘述,点开链接查看> 第二篇:库相关操作 一 系统数据库 information_schema: 虚拟库,不占用磁盘空间,存储的是数据库启动后的一些 ...