for循环添加的闭包问题
function test(){
var arr = [];
for (var i=0;i<;i++){
arr[i] = function(){
console.log(i);
}
}
return arr;
}
var myArr = test();
for (var i=0;i<myArr.length;i++){
myArr[i](); //结果为10个10
}
结果分析:
这是一个典型的闭包问题:
特点:arr[i] = function(){ console.log(i); } 中保存了i的引用,当myArr[i]()执行时,就要去寻找引用的上下文中的i
顺序:
函数提升和变量提升
1、GO
myArr:undefined;
test:function test(){};
i:0
2、test()执行
生成[[scope]]对象
[0]:test.AO{arr:[],i:10;}
注意:arr[i]和函数内的i是没有关系的;
[1]:GO
3、myArr[i]()执行的时候,test()已经执行完毕,会删除对执行上下文的引用,但是myArr[i]()没有删除对执行上下文的应用,还有每一次重新调用函数会重新生成一个执行上下文,和以前的执行上下文没有关系;
所以myArr[i]的所有的函数都指向一个执行上下文,也就指向同一个i;当test()执行完毕以后,i就已经变为10;所以当i=10 即10<10,条件不满足,所以停止;输出9个10
4、这个问题主要是执行上下文[[scope]]的AO和GO
解决办法:
function test(){
var arr = [];
for (var i=0;i<;i++){
(function(j){
arr[j]=function(){
console.log(j);
}
}(i))
}
return arr;
}
var myArr = test();
for (var i=0;i<myArr.length;i++){
myArr[i](); //结果为10个10
}
用闭包解决闭包问题
上一个问题,在于生成的10个函数同时指向同一个执行上下文,所以i会的值是统一的,当test()执行完毕i=10,并且断开对函数的AO的引用,但是闭包函数还在引用同一个AO所以i都等于10
解决办法是:
把每一个函数的指向的执行上下文单独独立开,10个函数有10个执行上下文,不指向同一个;
而且使用了立即执行函数,所以把i传给j,建立新的指向AO,每一次执行完函数销毁,会创建一个新的立即执行函数,所以指向的AO的上下文是不一样,不会受到影响

for循环添加的闭包问题的更多相关文章
- JS中for循环里面的闭包问题的原因及解决办法
我们先看一个正常的for循环,普通函数里面有一个for循环,for循环结束后最终返回结果数组 function box(){ var arr = []; for(var i=0;i<5;i++) ...
- JS给元素循环添加事件的问题
<ul> <li>男</li> <li>女</li> <li>老</li> <li>少</li&g ...
- js循环添加事件的问题
1.需求 给下面每个按钮增加事件 <ul id="list"> <li>按钮1</li> <li>按钮2</li> &l ...
- 关于for循环中的闭包问题
还是昨天的那个简单的小项目,已经花了一天的时间了 - - .从&&的用法,到CSStext,到今天马上要谈的闭包(closure),通过一个小东西,真真发现了自己的各方面不足.昨天发完 ...
- JS - 循环添加 DropDownList(Select)
代码: <td style="padding-left: 10px;"> <select id="ddl_picture_3"> < ...
- 【特效】给元素循环添加class
经常会遇到给元素循环添加class的效果,例如下面这个图 每个模块的背景色和图标都不相同,但是呢,模块的数量又不确定,说不定有几十个,那我不能设计几十个图标吧,所以,可以做成每9个一循环,也就是第10 ...
- select(有局限性),jq循环添加select的值
加载的时候改变select的默认值,只需改变select的value值 $("#one").val(@ViewBag.val);//@ViewBag.val是要默认选中的值的val ...
- Android及java中list循环添加时覆盖的问题-20171021
鉴于新浪博客太渣,转到这来. 最近在工程设计时,使用list循环添加map对象发现,最终全部变为最后一个map的值,但是list的数值还是正确的,也就是说添加了N(list长度或者说循环的次数)个相同 ...
- List循环添加数据覆盖问题
问题:java开发时,当我们使用List.add();循环添加数据,有时会出现前面添加的数据会被后面覆盖的现象.这是怎么回事尼? 会覆盖数据的代码 package com.boot.test; imp ...
随机推荐
- JAVA EXAM2 复习提纲
[真假分数相加] //inheritence, extends, use this & super 子类的方法 //two constructors, non-default use 'thi ...
- width多少,超过了用....表示
maxWidth:'140px',whiteSpace:'nowrap',overflow:'hidden',textOverflow:'ellipsis'
- linux命令学习之:ls
ls命令用来显示目标列表,在Linux中是使用率较高的命令.ls命令的输出信息可以进行彩色加亮显示,以分区不同类型的文件.语法 ls(选项)(参数) 选项说明 -a:显示所有档案及目录(ls内定将档案 ...
- vue-router2
六,导航钩子 导航钩子函数主要是在导航跳转的时候做一些操作,比如跳转页面之前,进行判断 进而选择跳转到哪里 钩子函数根据生效范围根据其生效范围可以分为全局钩子函数,路由独享钩子函数 和 组件钩子函数. ...
- 如何查看Firefox中保存的登录密码
问:以前使用Firefox浏览器登录一个论坛,并且临时申请了一个账号,在使用Firefox登录时选择让它记住密码了,后来,我忘记了那个论坛的密码,但是可以使用Firefox直接登录.现在能不能查看密码 ...
- MVC之CodeFirst
1.建立MVC项目>NuGet安装EF 2.建立模型: public class Blog { [Key] [DatabaseGenerated(DatabaseGeneratedOption. ...
- spirng中的asm与jdk不兼容<已解决>
转载自:spirng中的asm与jdk不兼容<已解决> 前言 不知道前面对eclipse做了什么,使用maven来创建项目,然后转成web,启动的时候一直报错.我弄了好久,还是无法解决,先 ...
- Oracle性能优化3-sql优化一定要等价
做sql优化的前提瞧见是sql等价 1.MAX MIN写法的分与合 drop table t purge; create table t as select * from dba_objects; a ...
- Linux操作系统-系统安装与分区
.磁盘分区 使用分区工具在磁盘上划分几个逻辑部分,一旦分成几个分区,不同类型的目录和文件可以存储进不同的分区2.分区类型主分区:最多只能有4个扩展分区:最多只能有1个:主分区加扩展分区最多有4个:扩展 ...
- 主机在无线网络的情况下,设置centos7.2虚拟机网络联通
1.vmvare中,编辑-虚拟网络编辑器 2.虚拟机设置 3.进入linux登录后 输入nmtui 4激活连接 5大功告成,输入ping www.baidu.com 发现ping通了