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

  1. <html >
  2. <head>
  3. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  4. <title>闭包演示</title>
  5. <script type="text/javascript">
  6. function init() {
  7. var pAry = document.getElementsByTagName("p");
  8. for( var i=0; i<pAry.length; i++ ) {
  9. pAry[i].onclick = function() {
  10. alert(i);
  11. }
  12. }
  13. }
  14. </script>
  15. </head>
  16. <body onload="init();">
  17. <p>产品一</p>
  18. <p>产品二</p>
  19. <p>产品三</p>
  20. <p>产品四</p>
  21. <p>产品五</p>
  22. </body>
  23. </html>

解决方式有以下几种

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

  1. function init() {
  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以函数参数形式传递给内层函数

  1. function init3() {
  2. var pAry = document.getElementsByTagName("p");
  3. for( var i=0; i<pAry.length; i++ ) {
  4. (function(arg){
  5. pAry[i].onclick = function() {
  6. alert(arg);
  7. };
  8. })(i);//调用时参数
  9. }
  10. }

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

  1. function init4() {
  2. var pAry = document.getElementsByTagName("p");
  3. for( var i=0; i<pAry.length; i++ ) {
  4. (function () {
  5. var temp = i;//调用时局部变量
  6. pAry[i].onclick = function() {
  7. alert(temp);
  8. }
  9. })();
  10. }
  11. }

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

  1. function init5() {
  2. var pAry = document.getElementsByTagName("p");
  3. for( var i=0; i<pAry.length; i++ ) {
  4. pAry[i].onclick = function(arg) {
  5. return function() {//返回一个函数
  6. alert(arg);
  7. }
  8. }(i);
  9. }
  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. }
 此博客转自其他博客

JavaScript for循环 闭包 【转】的更多相关文章

  1. JavaScript葵花宝典之闭包

    闭包,写过JS脚本的人对这个词一定不陌生,都说闭包是JS中最奇幻的一个知识点,  虽然在工作中,项目里经常都会用到~  但是是不是你已经真正的对它足够的了解~~ 又或者是你代码中出现的闭包,并不是你刻 ...

  2. 让你分分钟学会Javascript中的闭包

    Javascript中的闭包 前面的话: 闭包,是 javascript 中重要的一个概念,对于初学者来讲,闭包是一个特别抽象的概念,特别是ECMA规范给的定义,如果没有实战经验,你很难从定义去理解它 ...

  3. 深入理解javascript原型和闭包(4)——隐式原型

    注意:本文不是javascript基础教程,如果你没有接触过原型的基本知识,应该先去了解一下,推荐看<javascript高级程序设计(第三版)>第6章:面向对象的程序设计. 上节已经提到 ...

  4. 浅谈JavaScript中的闭包

    浅谈JavaScript中的闭包 在JavaScript中,闭包是指这样一个函数:它有权访问另一个函数作用域中的变量. 创建一个闭包的常用的方式:在一个函数内部创建另一个函数. 比如: functio ...

  5. javascript中的闭包解析

    学习javaScript已经有一段时间了,在这段时间里,已经感受到了JavaScript的种种魅力,这是一门神奇的语言,同时也是一门正在逐步完善的语言,相信在大家的逐步修改中,这门语言会逐步的完善下去 ...

  6. 《深入理解javascript原型和闭包系列》 知识点整理(转)

    深入理解javascript原型和闭包系列 对原型和闭包等相关知识的讲解,由浅入深,通俗易懂,每个字都值得细细研究. 一.一切都是对象 1. typeof操作符输出6种类型:string boolea ...

  7. 《深入理解javascript原型和闭包系列》 知识点整理

    深入理解javascript原型和闭包系列 对原型和闭包等相关知识的讲解,由浅入深,通俗易懂,每个字都值得细细研究. 一.一切都是对象 1. typeof操作符输出6种类型:string boolea ...

  8. JavaScript中的闭包理解

    原创文章,转载请注明:JavaScript中的闭包理解  By Lucio.Yang 1.JavaScript闭包 在小学期开发项目的时候,用node.js开发了服务器,过程中遇到了node.js的第 ...

  9. javascript作用域和闭包之我见

    javascript作用域和闭包之我见 看了<你不知道的JavaScript(上卷)>的第一部分--作用域和闭包,感受颇深,遂写一篇读书笔记加深印象.路过的大牛欢迎指点,对这方面不懂的同学 ...

随机推荐

  1. Enerprise Solution Main 启动方法源代码

    .NET 系统以Main方法作为应用程序的启动入口点,Enterprise Solution的启动程序源代码如下: [STAThread] static void Main() { string MA ...

  2. AJAX文件上传实践与分析,带HTML5文件上传API。

    对于HTML5已经支持AJAX文件上传了,但如果需要兼容的话还是得用一点小技巧的,HTML5等等介绍,先来看看以前我们是怎么写的. 网上可能会有一些叫AJAX文件上传插件,但在AJAX2.0之前是不可 ...

  3. maven+spring+springMVC+mybatis+dubbox

      milestone 2016612  dubbox+spring+mybatis provider调通

  4. C# 集合类 :(Array、 Arraylist、List、Hashtable、Dictionary、Stack、Queue)

    我们用的比较多的非泛型集合类主要有 ArrayList类 和 HashTable类.我们经常用HashTable 来存储将要写入到数据库或者返回的信息,在这之间要不断的进行类型的转化,增加了系统装箱和 ...

  5. 对类型“ImgProWPF.MainWindow”的构造函数执行符合指定的绑定约束的调用时引发了异常。

    这个问题的出现是在于我写的一句话 Icon = BitImg("Image/Icon.png") 其原因是Image/Icon.png路径不在执行的exe文件的目录下 将Image ...

  6. List和Dictionary泛型类查找效率浅析

    List和Dictionary泛型类查找效率存在巨大差异,前段时间亲历了一次.事情的背景是开发一个匹配程序,将书籍(BookID)推荐给网友(UserID),生成今日推荐数据时,有条规则是同一书籍七日 ...

  7. 【web前端面试题整理05】做几道前端面试题休息休息吧

    前言 连续学了两天javascript的东西了,我们都累了,于是今天还是上一套面试题吧,大家一起休息休息,也为下个星期可能会有的面试准备下. 题目一览 CSS1.  overflow-x  属于 CS ...

  8. expdp/impdp 参数说明,中英对照

    任意可以使用expdp/impdp的环境,都可以通过help=y看到帮助文档. 1.expdp参数说明 2.impdp参数说明 3.expdp参数说明(中文) 4.impdp参数说明(中文) 1.ex ...

  9. Azure Redis Cache (3) 在Windows 环境下使用Redis Benchmark

    <Windows Azure Platform 系列文章目录> 熟悉Redis环境的读者都知道,我们可以在Linux环境里,使用Redis Benchmark,测试Redis的性能. ht ...

  10. 年度榜单:2013年最佳免费 PSD 设计素材揭晓

    <年度榜单>系列继续给大家带来2013年度发布的好东西,这篇文章要给大家分享的是本年度最佳的12套精美的 PSD 设计素材,你可以免费下载使用.这些免费素材不仅能帮助他们节省大量的时间,而 ...