`
yanghuidang
  • 浏览: 914221 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

Javascript闭包演示

阅读更多

有个网友问了个问题,如下的html,为什么点击所有的段落p输出都是5,而不是alert出对应的0,1,2,3,4。

01 <!DOCTYPE HTML>
02 < html >
03 < head >
04 < meta charset = "utf-8" />
05 < title >闭包演示</ title >
06 < style type = "text/css" >
07      p {background:gold;}
08 </ style >
09 < script type = "text/javascript" >
10 function init() {   
11      var pAry = document.getElementsByTagName("p");   
12      for( var i=0; i< pAry.length ; i++ ) {   
13           pAry[i] .onclick = function () {   
14           alert(i);   
15      }
16    }
17 }
18 </script>
19 </ head >
20 < body onload = "init();" >
21 < p >产品 0</ p >
22 < p >产品 1</ p >
23 < p >产品 2</ p >
24 < p >产品 3</ p >
25 < p >产品 4</ p >
26 </ body >
27 </ html >


以上场景是初学者经常碰到的。即获取HTML元素集合,循环给元素添加事件。在事件响应函数中(event handler)获取对应的索引。但每次获取的都是最后一次循环的索引。

原因是初学者并未理解JavaScript的闭包特性。通过element.onclick=function(){alert(i);}方式给元 素添加点击事件。响应函数function(){alert(i);}中的 i 并非每次循环时对应的 i(如0,1,2,3,4)而是循环后最后 i 的值5。 或者说循环时响应函数内并未能保存对应的值 i,而是最后一次i++的值5。


了解了原因,摸索出了很多解决办法(纯粹是兴趣)。最先想到的前两种

1、将变量 i 保存给在每个段落对象(p)上

1 function init1() {
2    var pAry = document.getElementsByTagName( "p" );
3    for ( var i=0; i<pAry.length; i++ ) {
4       pAry[i].i = i;
5       pAry[i].onclick = function () {
6          alert( this .i);
7       }
8    }
9 }

2、将变量 i 保存在匿名函数自身

1 function init2() {
2    var pAry = document.getElementsByTagName( "p" );
3    for ( var i=0; i<pAry.length; i++ ) {
4     (pAry[i].onclick = function () {
5          alert(arguments.callee.i);
6      }).i = i;
7    }
8 }

 

后又想到了三种

3、加一层闭包,i 以函数参数形式传递给内层函数

01 function init3() {
02    var pAry = document.getElementsByTagName( "p" );
03    for ( var i=0; i<pAry.length; i++ ) {
04     ( function (arg){
05         pAry[i].onclick = function () {
06            alert(arg);
07         };
08     })(i); //调用时参数
09    }
10 }

4、加一层闭包,i 以局部变量形式传递给内层函数

01 function init4() {
02    var pAry = document.getElementsByTagName( "p" );
03    for ( var i=0; i<pAry.length; i++ ) {
04      ( function () {
05        var temp = i; //调用时局部变量
06        pAry[i].onclick = function () {
07          alert(temp);
08        }
09      })();
10    }
11 }

5、加一层闭包,返回一个函数作为响应事件(注意与3的细微区别)

01 function init5() {
02    var pAry = document.getElementsByTagName( "p" );
03    for ( var i=0; i<pAry.length; i++ ) {
04     pAry[i].onclick = function (arg) {
05         return function () { //返回一个函数
06         alert(arg);
07       }
08     }(i);
09    }
10 }

 

后又发现了两种

6、用Function实现,实际上每产生一个函数实例就会产生一个闭包

1 function init6() {
2      var pAry = document.getElementsByTagName( "p" );
3      for ( var i=0; i<pAry.length; i++ ) {
4        pAry[i].onclick = new Function( "alert(" + i + ");" ); //new一次就产生一个函数实例
5      }
6 }

7、用Function实现,注意与6的区别

1 function init7() {
2      var pAry = document.getElementsByTagName( "p" );
3      for ( var i=0; i<pAry.length; i++ ) {
4           pAry[i].onclick = Function( 'alert(' +i+ ')' );
5      }
6 }
2
5
分享到:
评论

相关推荐

    Javascript闭包演示代码小结

    闭包演示 p {background:gold;} function init() { var pAry = document.getElementsByTagName(“p”); for( var i=0; i 产品 0 产品 1 产品 2 产品 3 产品 4 [Ctrl+A 全选 注:如需引入外部Js需刷新才能执行]...

    JavaScript对闭包的理解.md

    为了帮助大家快速和较好地理解JavaScript函数中的闭包,本文对JavaScript的闭包进行了分析并进行简易的代码演示,希望本文能够给有需要的人带来一点小小的帮助。

    教你如何使用firebug调试功能了解javascript闭包和this

    想着趁机会将上面那篇闭包博文的配图用firebug再来演示一遍,也算是一点调试经验分享。 示例代码如下: 代码如下: function fn(){  var max = 10;  return function bar(x){  if (x &gt; max) {  console.log(x); ...

    闭包演示小

    闭包演示小

    Closures:这个存储库包含 JavaScript Closure 演示

    这个存储库包含JavaScript Closure演示。 在我们开始讨论闭包之前,重要的是我们理解以下术语,因为它们将构成我们对闭包的整个理解的基线: 1. 词法范围 词法是指语言或文本。 范围是指与文本相关的属性。 词法...

    浅谈JavaScript for循环 闭包

    有个网友问了个问题,如下的html,为什么每次输出都是5,而不是点击每个p...闭包演示&lt;/title&gt; [removed] function init() { var pAry = document.getElementsByTagName(p); for( var i=0; i&lt;pAry.length; i

    javascript 常见的闭包问题的解决办法

    –这就是闭包的问题 原来 在js中,函数中在定义函数,就出现闭包了。此时外层函数中变量是可以在里层函数里利用的,即使外层函数结束。但是当外层中出现循环的时候,如果在里层函数中利用这个循环变量的话,会直接...

    js-sandbox:了解和演示闭包的小型 js 测试

    js-闭包 用于理解和演示闭包、Web 套接字和 FP 等概念的小型 js 测试

    closures:您不会相信这种重写闭包的怪异方法

    上有幻灯片将代码转换为无闭包等效项要将某些常规JavaScript转换为演示的无封闭版本,请访问并添加一些代码。 请注意,它非常有限,不会处理任何边缘情况(例如,每行多个var声明,函数声明等)

    javascript全套教学资料(附全套知识点讲解)

    2. **高级特性深入解析**:覆盖了JavaScript语言的高级特性,如闭包、原型链、异步编程、模块化等,通过详细的讲解和实例演示帮助学习者理解和掌握这些复杂的概念和技术。 3. **DOM操作与事件处理**:介绍了DOM操作...

    jsct:演示应用程序-演示SPA和Backbone基础

    JavaScript代码跟踪器:骨干演示应用程序 JavaScript Code Tracker(JSCT)是一个简单的Web应用程序,演示了JavaScript单页应用程序(SPA)和Backbone(JavaScript MV *库)的一些基础知识。 JavaScript代码跟踪器...

    JavaScript 变量作用域及闭包第1/2页

    作用域JavaScript 的变量作用域是按照函数划分的,为了快速的了解它的特性,我们通过实例来进行演示。

    javascript-function:展示 javascript 函数强大功能的示例。 包括回调、动画定时器、闭包、柯里化、记忆

    演示文稿和代码来演示 JavaScript 函数的强大功能。 其目的是帮助来自传统面向对象语言(如 Java)的开发人员不支持一等功能,从而发挥语言的强大功能。 ###主题包括 函数返回 功能范围 关闭 回调 计时器 咖喱 ...

    JonasJavascript2021:完整JavaScript课程2021

    复杂的概念,例如“ this”关键字,高阶函数,闭包等。 如何使用流程图和通用模式来架构代码 练习50多项挑战和任务的技能 建立6个美丽的现实世界项目 项目的演示: 实时链接: 实时链接: 实时链接:

    dev-examples

    开发实例 组件 模态窗口(/) 表格(/) 导航(/) 基本示例(/ ) 范围自定义(/ ) 扰流板-详细信息(/ ) ... 使用闭包的总和(文件/演示) 闭包过滤(文件/ 演示) 呼叫计数器(文件/ 演示) 承

    谈谈JavaScript的New关键字

    原型和闭包算是JavaScript中最常见,最难以理解,最容易被当做问题的两个部分,当然还有它们的延伸,如作用域链,继承等等吧,我最近也是各种看,各种翻,记录点自己的心得,写写总会让自己的理解更深一些。...

    2017java源码-pycon2017-closures:PyconSK2017中的Python,Java,C#,JavaScript的幻灯

    演示还包括来自其他语言(例如Java,C#或Javascript)的示例。 滑梯 在根文件夹中检出pycon2017-closures.pdf 。 资料夹结构 python包含python中的示例 js包含javascript / node.js中的示例 csharp包含C#、. NET...

    closure-library-seed:Google Closure库的种子项目

    闭包库演示 与提出的申请,以生成。 当前未维护。 我花了一些时间使事情重新开始。 使用替换Grunt livereload。 当观看的文件发生更改时,它可以通知浏览器重新加载页面。 入门 启动服务器 grunt server 在...

    qr-scanner:轻量级 Javascript 二维码扫描器

    在此库中,对原始端口进行了多项改进: 开箱即用的网络摄像头扫描支持使用浏览器的本机 轻量级:~50.5 kB(~13.0 kB gzipped)用谷歌的闭包编译器缩小。 如果本机BarcodeDetector可用,则仅加载 ~6.8 kB(~2.7 kB ...

Global site tag (gtag.js) - Google Analytics