理解JS闭包的几个小实验
学了JavaScript有一段时间了,但是对闭包还是不太理解,于是怀着心中的疑问做了几个小实验,终于有点明白了。
首先看一下MDN上的定义:闭包是函数和声明该函数的词法环境的组合。
简单来说,闭包是一种现象。
我在搞清楚了2个概念后,理解了闭包。
首先是关于函数以及函数调用的概念:
我们来做一个简单的实验:
function foo () {
var a = 1;
function bar () {
console.log(a)
}
return bar;
} var first = foo();
console.log(first); // 显示结果:
// ƒ bar () {
// console.log(a)
// }
作为一个初学者,有一些小细节很容易干扰我的判断。
首先要理解的是function f () {}是在声明一个函数,要执行这个函数必须用f()进行调用。
f()调用函数后,js引擎会执行函数中的代码,如果函数最后有写return ...函数执行完毕才有返回值。
var first = foo();
表示把函数foo执行完毕后的返回值赋值给first,函数foo执行的操作是声明了一个变量a,以及一个函数bar,然后把函数bar作为返回值返回。注意:不是把bar的执行结果返回,而是把这个函数本身返回。所以first就指向了函数bar。
其次是关于执行环境与作用域的概念
作用域的定义:作用域是一套规则,用于确定在何处以及如何查找标识符。
我对作用域的理解是:代码起作用的范围。
执行环境的定义:执行环境定义了变量或函数有权访问的其他数据。每个执行环境都有三个重要的属性,变量对象(Variable object,VO)、作用域链(Scope chain)和 this。环境中定义的所有变量和函数都保存在变量对象中
我对执行环境的理解:存储一块代码中定义的所有的变量和函数的值。
因为全局作用域范围最广,所以函数内部也可以访问到全局变量。
函数内部代码执行的时候,发现某个变量的值在自己的执行环境中没有,就需要去上级执行环境中找。函数执行完毕后,当前函数的执行环境就被销毁,所以上级函数没有办法访问内部函数中声明的变量。
第二个小实验:
function foo () {
var a = 1;
function bar () {
console.log(a)
}
return bar;
} var first = foo();
console.dir(first);
显示结果如图所示:
first就是函数bar,它能访问自己的作用域,上级foo的作用域,以及全局作用域。
当js执行first的时候,first能访问自己的作用域,上级foo的作用域,以及全局作用域。这种现象就是闭包。
闭包最大用处有两个:一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。所以我们就可以利用闭包来创建模块机制:
function count() {
var number = 0;
return{
add : function(x){
if(x==undefined) {
number += 1;
}else{
number +=x;
}
},
reduce: function(x) {
if(x==undefined) {
number -= 1;
}else{
number -=x;
}
},
times: function() {
return number;
}
}
}
我们可以创建复数个加法器,而互不影响。
我关于闭包的理解就到这里了,如果你还不明白,就自己动手写代码试验吧!
理解JS闭包的几个小实验的更多相关文章
- javascript深入理解js闭包(转)
javascript深入理解js闭包 转载 2010-07-03 作者: 我要评论 闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. ...
- 理解JS闭包
从事web开发工作,尤其主要是做服务器端开发的,难免会对客户端语言JavaScript一些概念有些似懂非懂的,甚至仅停留在实现功能的层面上,接下来的文章,是记录我对JavaScript的一些概念的理解 ...
- js的一些常用判断小实验
下面是小实验案例 // 0 if(undefined) { console.log('1'); } else { console.log('0'); } // 0 if(null) { console ...
- 深入贯彻闭包思想,全面理解JS闭包形成过程
谈起闭包,它可是JavaScript两个核心技术之一(异步和闭包),在面试以及实际应用当中,我们都离不开它们,甚至可以说它们是衡量js工程师实力的一个重要指标.下面我们就罗列闭包的几个常见问题,从回答 ...
- javascript深入理解js闭包
一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量 ...
- 深入理解JS闭包
一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量 ...
- 通俗易懂的深入理解js闭包
闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. 一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域 ...
- 理解js闭包(二)
@(编程) 一.什么是闭包? 官方"的解释是:闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分. 相信很少有人能直接看懂这句话,因为他 ...
- javascript深入理解js闭包[转]
一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量 ...
随机推荐
- IT兄弟连 JavaWeb教程 AJAX中参数传递问题
使用Ajax发送GET请求并需要传递参数时,直接在URL地址后拼接参数,格式如下: xhr.open('get','请求路径?参数名1=参数值1&参数名2=参数值2...',true); 使用 ...
- python入门的基本历程
Python入门 1.1环境安装 python官网下载,安装之后添加环境变量. 1.2集成开发环境 PyCharm官网下载,安装后:new project-﹥pure python 设置python解 ...
- 跟踪记录ABAP对外部系统的RFC通信
对SAP系统而言,RFC最常见的系统间通信方式,SAP与SAP系统及SAP与非SAP系统之间的连接都可以使用它.它的使用便利,功能强大,在各种接口技术中,往往是最受(ABAP开发者)青睐的选择. 查询 ...
- java基础笔记(三)——main方法
1.解析public static void main(String[] args)方法 JVM在运行程序时,会首先查找main()方法作为入口,main是JVM识别的特殊方法名. public是权限 ...
- nutzboot 使用nacos替换zookeeper
先放一段从网上拷贝一段分布式CAP理论的概念 分布式领域中存在CAP理论,且该理论已被证明:任何分布式系统只可同时满足两点,无法三者兼顾. ①C:Consistency,一致性,数据一致更新,所有数据 ...
- ms sqlserver 清除数据库日志脚本
USE [master] GO ALTER DATABASE F360DW SET RECOVERY SIMPLE WITH NO_WAIT GO ALTER DATABASE F360DW SET ...
- SSIS连接-左外连接
应用场景: 当有多个数据源时,可能是在不同的数据库,或者是一个数据源来自数据库,另一个来自excel文件,想要把他们合并,像sql的左外联接时,应用到 源1: select 'A01' GoodsNo ...
- 重置 linux系统后要配置的基本组件操作
1.安装jdk https://www.cnblogs.com/shihaiming/p/5809553.html 2.安装mysql 3.安装tomcat
- .md文件插图片,不建议使用绝对地址。
一 主要有两种方法,一种绝对地址,一种相对地址. 而百度的话,全都是说绝对地址的. 但是,有很大的弊端啊 orz 二 先说绝对地址 ![image](https://github.com/AngelS ...
- vuex填坑记录
vuex是需要等待页面加载完成后才会更新的,如果页面点击刷新有用到vuex的地方,那么vuex会保持旧的数据,等刷新完成后vuex的数据才会重置,所以要在页面加载后再调用vuex的数据才是正确的,如果 ...