Javascirpt闭包问题以及解决方案
来源:互联网 发布:网页排版设计软件 编辑:程序博客网 时间:2024/06/16 07:43
HTML:
<button class="btn">点击</button><button class="btn">点击</button><button class="btn">点击</button>
js:
<span style="white-space:pre"></span>var btn=document.getElementsByClassName('btn');for(var i=0,len=btn.length;i<len;i++){btn[i].onclick=function(){console.log(i); // 3,3,3 }}
方案一:
解决思路:
增加若干个对应的闭包域空间(这里采用的是匿名函数)
专门用来存储原先需要引用的内容(下标),不过只限于基本类型
(基本类型值传递,引用类型引用传递)
<span style="white-space:pre"></span>for(var i=0,len=btn.length;i<len;i++){//声明一个匿名函数,若穿进来的是基本类型则为值传递,故不对实参产生影响(function(arg){btn[i].onclick=function(){// onclick函数实例的function scope的closure对象属性有一个引用arg,只要外部空间的arg不变,这里的引用值也不会改变console.log(arg);}})(i); // 立即执行该匿名函数,传递下标i(实参)}
解决思路二:
将下标作为对象属性(name:'i',value:i的值)添加到每个数组项中为当前数组项目即当前button对象添加一个名为i的属性,值为循环体的i变量的值;
此时当前button的对象的i属性并不是循环体i变量的引用,而是一个独立button对象的属性,属性值在声明的时候就确定了;
(基本类型的值都存在栈内存中,当有一个基本类型变量声明等于另一个基本变量时,此时并不是两个基本类型变量都指向了一个值,而是各自有各自的值,不过这两个值是相等的)
<span style="white-space:pre"></span>for(var i=0,len=btn.length;i<len;i++){btn[i].i=i;btn[i].onclick=function(){console.log(this.i);}}
解决思路三:
与解决方法一相似但又有点不太相似。相似点:同样是增加个若干个对应的闭包域空间来存储下标;
不同点:解决方法一是在新增的匿名闭包空间内完成事件的绑定,而此例是将事件绑定在新增的的匿名函数返回的函数上
此时绑定的函数中 function scope中的closure对象的引用arg是指向讲其返回的匿名函数的私有变量arg
<span style="white-space:pre"></span>for(var i=0,len=btn.length;i<len;i++){btn[i].onclick=(function(arg){return function(){console.log(arg);}})(i)}
解决方法四:
与方法一相似<span style="white-space:pre"></span>for(var i=0,len=btn.length;i<len;i++){(function(){var temp=i;btn[i].onclick=function(){console.log(temp);}})()}
解决方法五:
与方法三和四相似<span style="white-space:pre"></span>for(var i=0,len=btn.length;i<len;i++){btn[i].onclick=(function(){var temp=i;return function(){console.log(temp)}})()}
解决方法六:
将下标添加为绑定函数的属性<span style="white-space:pre"></span>for(var i=0,len=btn.length;i<len;i++){(btn[i].onclick=function(){console.log(arguments.callee.i);}).i=i;}
解决方法七:
通过new使用Function的构造函数创建Function实例实现,由于传入的函数体的内容是字符串故Function得到的是一个字符串拷贝,而没有得到i的引用(这里先获取i.toString()然后与前后字符串拼接成一个新的的字符串,Funciton对其进行反向解析成JS代码)
<span style="white-space:pre"></span>for(var i=0,len=btn.length;i<len;i++){btn[i].onclick=new Function("console.log("+i+");")}感谢Tomson的解决方案点击打开链接
0 0
- Javascirpt闭包问题以及解决方案
- javascirpt 的闭包----我的简介
- udp 丢包问题以及解决方案
- androidStudio V4包冲突问题以及解决方案
- 问题以及解决方案
- 嵌入式 Linux下如何安装rpm包以及相关问题的解决方案
- 嵌入式 Linux下如何安装rpm包以及相关问题的解决方案
- 给空签名包进行签名以及找不到keystore证书链问题的解决方案
- jar hell问题以及解决方案
- Hbase性能问题以及解决方案
- 项目问题以及解决方案记录
- for循环中的闭包问题及解决方案
- JavaScript动态事件以及闭包问题的解决
- Javascript作用域、闭包原理以及性能问题
- Javascript作用域、闭包原理以及性能问题
- javascript作用域、闭包原理以及性能问题
- JS的作用域、闭包原理以及性能问题
- JavaScript之闭包问题以及立即执行函数
- RSTP服务器架设
- tarjan算法求强连通分量
- 输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排列出来的所有字符串abc,acb,bac,bca,cab和cba。 结果请按字母顺序输出。
- 121. Best Time to Buy and Sell Stock
- git管理冲突及Fastjson用法
- Javascirpt闭包问题以及解决方案
- Picasso和Glide的区别
- 如何让WMI进程独立固定端口
- 【Android死丢丢】在AndroidStudio中使用Lambda表达式
- swift之"ambiguous use of subscript"
- 【记录】LED
- break and coutinue在遇到switch的不同
- csdn待改进点之31------>无登录态时去点赞,点不了是合理的(基于游客不能点赞), 但为什么不给用户提示? 为什么不直接跳转到登录页?
- pixhawk Lacal_position_estimator数据流