深入理解JavaScript (5) —— 闭包
理解了上下文环境、作用域、作用域链以及自由变量,我们再来聊聊闭包。
我们不急于给出闭包的概念,先从应用闭包的两种情况 —— 1.函数作为返回值,2.函数作为参数被传递 —— 来直观的认识它。
第一,函数作为返回值
function fn() {var max = 10;return function bar(x) {if( x > max ) {console.log(x);}};
}var f1 = fn();
f1(15);
如上代码,bar函数作为返回值,赋值给f1变量。执行f1(15)时,用到了fn作用域下的max变量的值。至于如何跨作用域取值,可以参考上一节。
第二,函数作为参数被传递
var max = 10,fn = function(x) {console.log( x > max ? true : false );};(function(f) {var max = 100;f(20);
})(fn);
如上代码中,fn函数作为一个参数被传递进入另一个函数,赋值给f参数。执行f(20)时,max变量的取值是10,而不是100,所以打印结果是true。
上一节讲到自由变量跨作用域取值时,曾经强调过:要去创建这个函数的作用域取值,而不是“父作用域”。理解了这一点,以上两段代码中,自由变量如何取值应该比较简单。
以上是从作用域的角度对闭包的理解,我们还可以结合执行上下文栈来理解闭包。
在前面讲执行上下文栈时说到,有些情况下,函数调用完成之后,其执行上下文环境不会接着被销毁。这就是需要理解闭包的核心内容。
咱们可以拿本文的第一段代码(稍作修改)来分析一下。
第一步,代码执行前(预处理阶段)生成全局上下文环境,并在执行时对其中的变量进行赋值。此时全局上下文环境是活动状态。
图片描述
第二步,执行第17行代码时,调用fn(),产生fn()执行上下文环境,压栈,并设置为活动状态。
第三步,执行完第17行,fn()调用完成。按理说应该销毁掉fn()的执行上下文环境,但是这里不能这么做。注意,重点来了:因为执行fn()时,返回的是一个函数。函数的特别之处在于可以创建一个独立的作用域。而正巧合的是,返回的这个函数体中,还有一个自由变量max要引用fn作用域下的fn()上下文环境中的max。因此,这个max不能被销毁,销毁了之后bar函数中的max就找不到值了。
因此,这里的fn()上下文环境不能被销毁,还依然存在与执行上下文栈中。
——即,执行到第18行时,全局上下文环境将变为活动状态,但是fn()上下文环境依然会在执行上下文栈中。另外,执行完第18行,全局上下文环境中的max被赋值为100。如下图:
第四步,执行到第20行,执行f1(15),即执行bar(15),创建bar(15)上下文环境,并将其设置为活动状态。
执行bar(15)时,max是自由变量,需要向创建bar函数的作用域中查找,找到了max的值为10。这个过程在作用域链一节已经讲过。
这里的重点就在于,创建bar函数是在执行fn()时创建的。fn()早就执行结束了,但是fn()执行上下文环境还存在与栈中,因此bar(15)时,max可以查找到。如果fn()上下文环境销毁了,那么max就找不到了。
使用闭包会增加内容开销,现在很明显了吧!
第五步,执行完20行就是上下文环境的销毁过程,这里就不再赘述了。
深入理解JavaScript (5) —— 闭包相关推荐
- 深入理解javascript的闭包
闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. 一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域 ...
- 深入理解JavaScript的闭包特性如何给循环中的对象添加事件
初学者经常碰到的,即获取HTML元素集合,循环给元素添加事件.在事件响应函数中(event handler)获取对应的索引.但每次获取的都是最后一次循环的索引.原因是初学者并未理解JavaScript ...
- 如果理解Javascript利用闭包循环绑定事件
我们先看一个关于Javascript利用循环绑定事件的例子: 例如:一个不确定长度的列表,在鼠标经过某一条的时候改变背景. <!DOCTYPE html PUBLIC "-//W3C/ ...
- [转载]深入理解JavaScript闭包(closure)
最近在网上查阅了不少Javascript闭包(closure)相关的资料,写的大多是非常的学术和专业.对于初学者来说别说理解闭包了,就连文字叙述都很难看懂.撰写此文的目的就是用最通俗的文字揭开Java ...
- 深入理解JavaScript闭包(closure) 【收藏】
深入理解JavaScript闭包(closure) 原文地址:http://www.felixwoo.com/archives/247 Felix Woo 最近在网上查阅了不少Javascript闭 ...
- 【转】深入理解JavaScript闭包(closure)
文章来源:http://www.felixwoo.com/archives/247 最近在网上查阅了不少Javascript闭包(closure)相关的资料,写的大多是非常的学术和专业.对于初学者来说 ...
- 让你分分钟理解 JavaScript 闭包
原文:https://www.cnblogs.com/onepixel/p/5062456.html 让你分分钟理解 JavaScript 闭包 闭包,是 Javascript 比较重要的一个概念,对 ...
- 全面理解Javascript闭包和闭包的几种写法及用途--转载自https://www.cnblogs.com/yunfeifei/p/4019504.html...
全面理解Javascript闭包和闭包的几种写法及用途 好久没有写博客了,过了一个十一长假都变懒了,今天总算是恢复状态了.好了,进入正题,今天来说一说javascript里面的闭包吧!本篇博客主要讲一 ...
- 深入理解Javascript闭包(一)
闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. 一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用于.变量作用域包括 ...
- 深入理解javascript原型和闭包(16)——完结
之前一共用15篇文章,把javascript的原型和闭包. 首先,javascript本来就"不容易学".不是说它有多难,而是学习它的人,往往都是在学会了其他语言之后,又学java ...
最新文章
- Cocoa 框架 For iOS(二)对象的分配初始化、内省、单例
- 如果通过当前元素知道父元素、同级元素
- JVM专题(2)-类加载器子系统
- 【深度学习】深度学习中的知识蒸馏技术(上)简介
- MFC中打开文件对话框:CFileDlg
- echarts的词云图表类型有哪些_数据可视化之常见12种图表类型分析
- JDK源码包结构分类
- python爬虫数据可视化软件_python爬虫及数据可视化分析
- 清除tomcat缓存
- python正则表达式re模块_详解Python正则表达式re模块
- java入门到精通6版pdf_java从入门到精通第6章.pdf
- JS实现图片拖动验证
- anguarjs 图片预览_一键精准提取图片文字,这么高效的app确定不盘一下嘛
- Twaver-HTML5基础学习(26)背景
- 新型智能优化算法——海鸥优化算法(基于Matlab代码实现)
- coldwallet java eth,使用Web3j(JAVA)开发ETH钱包-2
- Deamon有名的守护进程
- 科学与财富杂志科学与财富杂志社科学与财富编辑部2022年第27期目录
- Mybatis的一个连接mysql的坑
- 基于单片机控制的开关电源设计