web前端学习:深入理解JS闭包
第一部分:初遇闭包
http://www.runoob.com/js/js-function-closures.html
什么是闭包?闭包有什么作用?这是我遇到闭包时的第一反应。
闭包在JavaScript高级程序设计(第3版)中是这样描述:闭包是指有权访问另一个函数作用域中的变量的函数。
那么闭包的作用也就很明显了。
1. 可以在函数的外部访问到函数内部的局部变量。
2. 让这些变量始终保存在内存中,不会随着函数的结束而自动销毁。
在上面的代码中,闭包指的就是function () {return counter += 1;}这个函数。首先解释一下这段代码,在变量add被赋值之前,第一个function执行了一次(执行且仅会执行一次),因为这是一个函数表达式声明方式并且声明后加上了(),所以会自动执行一次。执行后add被赋值(匿名函数)了,add= function () {return counter += 1;}。然后每次调用add()函数时,返回的都是这个函数,因为这个函数在第一个函数的内部,所以即使第一个函数执行完了,第二个函数依然能访问counter(JS设计的作用域链,当前作用域能访问上级的作用域)。
闭包是可以在另一个函数的外部访问到其作用域中的变量的函数。而被访问的变量可以和函数一同存在。即使另一个函数已经运行结束,导致创建变量的环境销毁,也依然会存在,直到访问变量的那个函数被销毁。当然,如果仅仅是做一个简单的计数器,大可不用这样麻烦。下面这简短的代码就能轻松实现。
var a = 0;
function myFunction(){
a++;
document.getElementById("demo").innerHTML = a;
}
第二部分:牛客翻船
https://www.nowcoder.com/questionTerminal/da4115e308c948169a9a73e50d09a3e7
下面是这个题目的解答:
每个li标签的onclick事件执行时,本身onclick绑定的function的作用域中没有变量i,i为undefined,则解析引擎会寻找父级作用域,发现父级作用域中有i,且for循环绑定事件结束后,i已经赋值为4,所以每个li标签的onclick事件执行时,alert的都是父作用域中的i,也就是4。这是作用域的问题。
闭包只能取得包含函数中任何变量的最后一个值。因为别忘了闭包所保存的是整个变量对象,而不是某个特殊的变量。
这是在循环体中创建闭包的常见错误。https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Closures(一定要看这篇)
这里面给onclick赋值的是闭包。很多人会问为什么是闭包?之前闭包不是函数A里的函数B吗?函数B用来访问函数A的变量,称函数B是闭包,题目中只有一个函数为什么也是闭包。其实,用两个函数形成闭包只是一般形式。闭包真正的含义是,如果一个函数访问了此函数的父级及父级以上的作用域变量,就可以称这个函数是一个闭包。
var a = 1;
(function test (){
alert(a);
})()
所以上面的function都可以称之为闭包(匿名闭包函数)。
这里还是作用域的问题,那么我们把每次的i都保存到一个变量中,匿名闭包就可以实现想要的效果。
这样就使用了闭包,这里面的闭包指的是function() {alert(num);};第二个function里面弹出的num是第一个function的参数,通过(i)执行了这里面的第一个函数,同时i的值被保存到num中。每个点击事件中都有一个局部变量num,num保存的是相应的i值。
上面的牛客题目只需要将for(var i=0;ihttps://mp.csdn.net/postedit/81065540
let的到来,让令人诟病的JS获得了一丝生机,也补上了JS没有块级作用域的短板。ECMAScript6还有很多新特性,笔者也在不断学习中。
函数工厂和闭包模拟私有方法
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Closures(这篇讲得很好,希望大家读透)
感谢阅读
喜欢看小编文章的点个订阅或者喜欢!小编每天都会跟大家分享文章,也会给大家提供web前端学习资料。

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
贪心算法
贪心的过程要么是最大要么是最小,堆可以很好的满足这个要求。 问题1:一块金条切成两半,是需要花费和长度数值一样的铜板的。比如 长度为20的 金条,不管切成长度多大的两半,都要花费20个铜 板。一群人想整分整块金 条,怎么分最省铜板? 例如,给定数组{10,20,30},代表一共三个人,整块金条长度为 10+20+30=60. 金条要分成10,20,30三个部分。 如果, 先把长 度60的金条分成10和50,花费60 再把长度50的金条分成20和30, 花费50 一共花费110铜板。 但是如果, 先把长度60的金条分成30和30,花费60 再把长度30 金条分成10和20,花费30 一共花费90铜板。 输入一个数组,返回分割的最小代价。 import java.util.Comparator; import java.util.PriorityQueue; public class ddd { public int lessMoney(int[] array){ PriorityQueue<Integer> minHeap = new PriorityQueue<>...
- 下一篇
C++入门:与Python对比第一弹
因为下学期会学c++面向对象编程,还有接下来的项目中可能会用到c++,所以决定先提前学习下,顺便与python做个比对,还是有许多相似之处的。=v= 下面是两个简单例子对比。 1,for循环 C++ #include <iostream> using namespace std; int main() { int a = 5; for (a; a < 10; a += 1) { cout << "a的值为:" << a << endl; } system("PAUSE"); return 0; } Python for a in range(5, 10): if a < 10: print('a的值为:', a) a += 1 else: break 输出都为: a的值为: 5 a的值为: 6 a的值为: 7 a的值为: 8 a的值为: 9 2,while循环 C++ #include <iostream> using namespace std; int main () { int a = 5; while( a...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- SpringBoot2整合Thymeleaf,官方推荐html解决方案
- Linux系统CentOS6、CentOS7手动修改IP地址
- CentOS8安装Docker,最新的服务器搭配容器使用
- CentOS7安装Docker,走上虚拟化容器引擎之路
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- Docker安装Oracle12C,快速搭建Oracle学习环境
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- CentOS7,8上快速安装Gitea,搭建Git服务器