`
yanghuidang
  • 浏览: 954879 次
  • 性别: 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 闭包实例下载

    JavaScript 闭包是一种高级编程概念,它在JavaScript中扮演着至关重要的角色,特别是在函数式编程和模块化设计中。闭包本质上是函数和其能够访问...通过学习这些实例,你将能够更好地掌握JavaScript闭包这一核心概念。

    JavaScript对闭包的理解.md

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

    javascript演示程序

    在这个"javascript演示程序"中,我们可以深入理解JavaScript的核心概念和常见应用。 首先,JavaScript的基本语法与C++和Java类似,它包括变量、数据类型(如字符串、数字、布尔值、对象等)、运算符、控制结构(如...

    javascript代码和网页演示

    在本资料的"javascript代码和网页演示_PART4"中,可能包含了一些高级话题,如事件处理、AJAX异步通信、闭包、原型链等。事件处理是JavaScript与用户交互的关键,当用户点击按钮、滚动页面等,对应的事件处理器会被...

    理解javascript闭包

    JavaScript闭包是这门语言的核心概念之一,它允许函数访问外部函数中的局部变量、参数和内部定义的其他函数。闭包的创建通常发生在函数被返回并赋值给一个全局变量时,即使外部函数已经执行完毕,这些变量也不会被...

    闭包演示小

    闭包是JavaScript编程中一个非常重要的概念,它在函数式编程和对象封装中扮演着核心角色。闭包简单来说就是能够记住其词法作用域(定义时的作用域)的函数,即使该函数在外部作用域被调用。这种特性使得闭包在管理...

    javascript经典特效---病毒入侵演示.rar

    7. **闭包**:JavaScript的闭包特性可以用来管理作用域,保护内部变量不被外部访问,同时在动画执行过程中保持状态。 8. **性能优化**:对于大规模的病毒元素,可能需要考虑性能优化,比如使用...

    JavaScript 例子(JavaScript 源码html格式)

    例子将演示如何处理回调函数、Promise链式调用以及异步操作的错误处理。 7. **JavaScript模板字符串**:模板字符串是ES6引入的新特性,允许在字符串中嵌入表达式。例子可能包含使用模板字符串构建动态HTML内容的...

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

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

    带演示的常用Javascript特效代码集

    这个"带演示的常用Javascript特效代码集"包含了多种常见的JavaScript特效实现,对于开发者来说是一份宝贵的参考资料。以下是对其中可能包含的知识点的详细说明: 1. **DOM操作**:在JavaScript中,DOM(Document ...

    JavaScript学习笔记-适合初学者

    最后,"JavaScript.ppt"可能是JavaScript的演示文稿,包含了语言的主要知识点和实例,可能涵盖从基础到进阶的主题,如闭包、异步编程、AJAX(异步JavaScript和XML)以及ES6的新特性,如箭头函数、模板字符串、...

    顽皮的闭包

    通常,开发者会编写测试用例来演示闭包如何工作,例如,如何使用闭包来保存状态、创建私有变量或者实现异步操作的回调函数等。 在标签中,“源码”意味着我们将探讨闭包在实际代码中的应用,理解其底层工作原理。而...

    浅谈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(John Resig)

    书中详细阐述了这些基础知识,并通过实例演示如何在实际编程中应用它们。 其次,JavaScript的面向对象特性是其重要组成部分。书中会讲解如何使用构造函数、原型链以及闭包来实现面向对象编程。此外,ES6引入的类和...

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

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

Global site tag (gtag.js) - Google Analytics