JS闭包以及作用域初探
以前看到的一个问题,很有意思:
for (var i = 0; i < 5; i++) {
setTimeout(function () {
console.log(i);
},500);
}
循环5个setTimeout, 你会发现console.log的值都是5. 为什么呢,因为setTimeout是个异步函数,for在执行的时候会直接跳过,很明显这里是先执行了循环,setTimeout才开始执行,这个时候变量i 的值已经是5了,所以接连输出5个5.
但是我们不需要这样的结果,我们希望每个i在每个setTimeout的值跟随for循环来变,于是:
for (var i = 0; i < 5; i++) {
(function (i) {
setTimeout(function () {
console.log(i);
}, 500);
})(i);
}
我们使用了一个闭包的匿名函数,每次循环的时候将变量i传进这个“封闭”着的函数里,这样setTimeout里面使用到的i的每个值都不一样,用我的理解就是,闭包使 i 独立了,外部依次传入5个不同的I,这个5个i彼此隔离,在自己的setTimeout里被使用。
关于闭包是什么,网上有很多解答, http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html 这个人讲得挺细的了
回到主题,上面为了是每个setTimeout里输出的值都是当前循环里的值,使用到了闭包,但是还有一种简洁的写法:
for (let i = 0; i < 5; i++) {
setTimeout(function () {
console.log(i);
}, 500);
}
使用let以后i的作用域就变成块级作用域了,setTimeout里的每个i都是当前循环里的i,所以最后得到的结果就不是同一个了,而是我们想要的结果!
JS闭包以及作用域初探的更多相关文章
- js闭包的作用域以及闭包案列的介绍:
转载▼ 标签: it js闭包的作用域以及闭包案列的介绍: 首先我们根据前面的介绍来分析js闭包有什么作用,他会给我们编程带来什么好处? 闭包是为了更方便我们在处理js函数的时候会遇到以下的几 ...
- 那些年我们一起过的JS闭包,作用域,this,让我们一起划上完美的句号。
之前有写过闭包,作用域,this方面的文章,但现在想想当时写的真是废话太多了,以至于绕来绕去的,让新手反而更难理解了,所以就有了此篇文章,也好和闭包,作用域,this告一段落. 第一个问题:什么是闭包 ...
- js 闭包,作用域,this 终结篇(转)
之前有写过闭包,作用域,this方面的文章,但现在想想当时写的真是废话太多了,以至于绕来绕去的,让新手反而更难理解了,所以就有了此篇文章,也好和闭包,作用域,this告一段落. 第一个问题:什么是闭包 ...
- JS闭包、作用域链、垃圾回收、内存泄露相关知识小结
补充: 闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. 闭包的三个特性: 1.函数嵌套函数 2.函数内部可以引用外部的参数和变量 3.参数和变 ...
- 聊一下JS中的作用域scope和闭包closure
聊一下JS中的作用域scope和闭包closure scope和closure是javascript中两个非常关键的概念,前者JS用多了还比较好理解,closure就不一样了.我就被这个概念困扰了很久 ...
- 对JS闭包和函数作用域的问题的深入讨论,如何理解JS闭包和函数作用域链?
首先先引用<JavaScript权威指南>里面的一句话来开始我的博客:函数的执行依赖于变量作用域,这个作用域是在函数定义时决定的,而不是函数调用时决定的. 因此,就出现了如下的几串代码: ...
- JS中的作用域和闭包
作用域:在编程语言中,作用域控制着变量与参数的可见性及生命周期.JS确实有函数作用域,那意味着定义在函数中的参数和变量在函数外部是不可见的,而且在一个函数中的任何位置定义的变量在该函数中的任何地方都是 ...
- [ JS 进阶 ] 闭包,作用域链,垃圾回收,内存泄露
原网址:https://segmentfault.com/a/1190000002778015 1. 什么是闭包? 来看一些关于闭包的定义: 闭包是指有权访问另一个函数作用域中变量的函数 --< ...
- JS详细图解作用域链与闭包
JS详细图解作用域链与闭包 攻克闭包难题 初学JavaScript的时候,我在学习闭包上,走了很多弯路.而这次重新回过头来对基础知识进行梳理,要讲清楚闭包,也是一个非常大的挑战. 闭包有多重要?如果你 ...
随机推荐
- 编译percona-server-locks-detail-5.7.22
yum install -y binutils compat-libstdc++ gcc gcc-c++ glibc glibc-devel ksh libaio libaio-devel libgc ...
- Cs231n课堂内容记录-Lecture2-Part1 图像分类
Lecture 2 课程内容记录:(上)https://zhuanlan.zhihu.com/p/20894041?refer=intelligentunit (下)https://zhuanlan. ...
- 在MFC Dialog中显示cmd窗口
打开Project -> Properties,在Build Events -> Post-Build Event里的Command Line中输入: editbin /SUBSYSTEM ...
- cmd是命令提示符吗?
经常使用电脑的小伙伴对cmd有所了解,它能帮我们快速解决问题.搜索框中输入“cmd”,就可以看到命令提示符程序了.那么,命令提示符程序和cmd到底有着什么样的联系呢?下面就为大家讲解一下. CMD是c ...
- LeetCode算法题-Remove Linked List Elements(Java实现)
这是悦乐书的第189次更新,第191篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第48题(顺位题号是203).移除单链表中节点值为val的节点.例如: 输入:1-> ...
- LeetCode算法题-Excel Sheet Column Number(Java实现)
这是悦乐书的第182次更新,第184篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第41题(顺位题号是171).给定Excel工作表中显示的列标题,返回其对应的列号.例如 ...
- Elixir 单元测试
概述 elixir 中自带了单元测试框架 ExUnit ,其中提供单元测试的一系列,主要包含以下模块: ExUnit: 单元测试框架 ExUnit.Assertions: 断言 ExUnit.Case ...
- March 11th, 2018 Week 11th Sunday
All good things must come to an end. 好景无常. Love is when the other person's happiness is more importa ...
- Vue+Webpack常见问题(持续更新)
常识 1.computed计算属性,使用的属性必需在data里面声明. computed: { canLogin: function(){ //注意这里的依赖的属性必需在data里面声明 return ...
- 常见C语言内存错误
前言 C语言强大的原因之一在于几乎能掌控所有的细节,包括对内存的处理,什么时候使用内存,使用了多少内存,什么时候该释放内存,这都在程序员的掌控之中.而不像Java中,程序员是不需要花太多精力去处理垃圾 ...