<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title></title>
<script type="text/javascript">
//面试经典问题: function onMyLoad(){
/*
抛出问题:
此题的目的是想每次点击对应目标时弹出对应的数字下标 0~4,但实际是无论点击哪个目标都会弹出数字5
*/
var arr = document.getElementsByTagName("p");
for(var i = 0; i < arr.length;i++){
arr[i].onclick = function(){
alert(i);
}
}
}
</script>
</head>
<body onload="onMyLoad()">
<p>产品一</p>
<p>产品二</p>
<p>产品三</p>
<p>产品四</p>
<p>产品五</p>
</body>
</html>

  本来以为只是个小循环,没想到一下掉坑里了.

搜索良久,,对闭包还是理解不了,,暂时找到几种方法算好理解的:

one:

/*
解决思路:
增加若干个对应的闭包域空间(这里采用的是匿名函数),专门用来存储原先需要引用的内容(下标),不过只限于基本类型(基本类型值传递,对象类型引用传递)
*/
for(var i = 0;i<arr.length;i++){ //声明一个匿名函数,若传进来的是基本类型则为值传递,故不会对实参产生影响,
//该函数对象有一个本地私有变量arg(形参) ,该函数的 function scope 的 closure 对象属性有两个引用,一个是 arr,一个是 i
//尽管引用 i 的值随外部改变 ,但本地私有变量(形参) arg 不会受影响,其值在一开始被调用的时候就决定了.
(function (arg) {
arr[i].onclick = function () { //onclick函数实例的 function scope 的 closure 对象属性有一个引用 arg,
alert(arg); //只要 外部空间的 arg 不变,这里的引用值当然不会改变
}
})(i); //立刻执行该匿名函数,传递下标 i(实参)
}

  two:

/*
解决思路:
将下标作为对象属性(name:"i",value:i的值)添加到每个数组项(p对象)中
*/
for(var i = 0;i<arr.length;i++){
//为当前数组项即当前 p 对象添加一个名为 i 的属性,值为循环体的 i 变量的值,
//此时当前 p 对象的 i 属性并不是对循环体的 i 变量的引用,而是一个独立p 对象的属性,属性值在声明的时候就确定了
//(基本类型的值都是存在栈中的,当有一个基本类型变量声明其等于另一个基本变量时,此时并不是两个基本类型变量都指向一个值,而是各自有各自的值,但值是相等的)
arr[i].i = i;
arr[i].onclick = function () {
alert(this.i);
}
}

  three:

/*
解决思路:
与解决办法一有点相似但却有点不太相似.
相似点:同样是增加若干个对应的闭包域空间用来存储下标
不同点:解决办法一是在新增的匿名闭包空间内完成事件的绑定,而此例是将事件绑定在新增的匿名函数返回的函数上 此时绑定的函数中的 function scope 中的 closure 对象的 引用 arg 是指向将其返回的匿名函数的私有变量 arg
*/
for(var i = 0; i<arr.length;i++){
arr[i].onclick = (function(arg){
return function () {
alert(arg);
}
})(i);
}

  

懵逼的闭包--for循环(转)的更多相关文章

  1. swift中闭包的循环引用

    首先我们先创造一个循环引用 var nameB:(()->())? override func viewDidLoad() { super.viewDidLoad() let bu = UIBu ...

  2. 前端(十三)—— JavaScript高级:回调函数、闭包、循环绑定、面向对象、定时器

    回调函数.闭包.循环绑定.面向对象.定时器 一.函数高级 1.函数回调 // 回调函数 function callback(data) {} // 逻辑函数 function func(callbac ...

  3. Swift 闭包使用(循环引用...)

    class networkTool: NSObject { //定义一个可选类型的闭包,用小括号()?括起闭包 var finishedCallBack2:((_ jsonData:String)-& ...

  4. JS闭包导致循环给按钮添加事件时总是执行最后一个

    加入如下脚本代码: <script> var list_obj = document.getElementsByTagName('li'); for (var i = 0; i <= ...

  5. 闭包 (循环事件获取不到i) 和 各种解决循环获取不到i的解决方法

    for(var i in fav){ (function(){                var p=i;                var obj=$S.getId(fav[i]);     ...

  6. Xcode8的调试技能Memory Graph 实战解决闭包引用循环问题

    Xcode8的调试技能又增加了一个黑科技:Memory Graph.简单的说就是可以在运行时将内存中的对象生成一张图. 那么通过一个实际项目来练习一下吧. 首先我们写了一个自定义UIView:MyVi ...

  7. JS高阶---闭包(循环遍历+监听)

    大纲: 主体: (1)场景1:点击按钮显示点击的第几个 注意:伪数组每次循环时都会重新计算一次长度,所以最好提出去或者直接加到for循环内部 结果: 分析: 1.i为全局变量 解决方案: 1.下标法 ...

  8. js闭包for循环总是只执行最后一个值得解决方法

    <style> li{ list-style: none;width:40px;height: 40px;text-align:center;line-height: 40px;curso ...

  9. Js闭包与循环

    目标:点击任何一个li,提示当前点击位置 <ul> <li>第1个</li> <li>第2个</li> <li>第3个</ ...

随机推荐

  1. add添加

    s = {1,2,3,4,5,6,} 进行添加数据! s = {1,2,3,4,5,6,} s.add('s')#添加字符串's' s.add('3')#添加字符串'3' s.add(3)#添加3和字 ...

  2. android MVC && MVP && MVVM分析和对比

    相关:http://www.cnblogs.com/wytiger/p/5305087.html 出处http://blog.csdn.net/self_study,对技术感兴趣的同鞋加群544645 ...

  3. VS 团队资源管理 强制解锁锁定文件

    故事是这样发生的: 以前有台电脑,在团队资源里看程序,可能冥冥中不小心按了个空格,so,文件被锁定 而我却没有发现 如果再给我一个机会,我只想说记得签入 然后,高潮来了 重装电脑 欣喜的装好新机子打开 ...

  4. 设置 github 帐号user.name和邮箱user.email

    git config --global user.name username git config --global user.email username@email.com

  5. 配置springMVC之后,引入js,css等资源处理

    配置了sringMVC之后,要引入js,css处理: 做法1:在<%page %>下面增加: <%@ taglib prefix="yesurl" uri=&qu ...

  6. fedora22命令useradd,groupadd等命令不能自动补全

    sudo ls -l /sbin/useradd 发现登陆账户没有读权限 修改为其他账户为读权限即可

  7. IE8的parseInt

    踩到一个IE8的parseInt的坑: Chrome:

  8. Linux系统下的程序开发之:命名规范

    2016年12月13日16:19:53 ------------------------------- 不能使用类似驼峰法的命名文件:dingdanOrder.html 这样的命名,会让系统无法找到目 ...

  9. 【Beta】七天屠蛟记

    团队名字: 一不小心就火了 屠龙天团少年们: 031402504 陈逸超 (组长) 031402505 陈少铭 031402511 黄家俊 031402515 翁祖航 031402516 黄瑞钰 03 ...

  10. PL/SQL 将旧表的一些字段赋值给新的表中的字段的做法

    INSERT INTO 新表(字段1,字段2,.......) SELECT 字段1,字段2,...... FROM 旧表