学了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闭包的几个小实验的更多相关文章

  1. javascript深入理解js闭包(转)

    javascript深入理解js闭包 转载  2010-07-03   作者:    我要评论 闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. ...

  2. 理解JS闭包

    从事web开发工作,尤其主要是做服务器端开发的,难免会对客户端语言JavaScript一些概念有些似懂非懂的,甚至仅停留在实现功能的层面上,接下来的文章,是记录我对JavaScript的一些概念的理解 ...

  3. js的一些常用判断小实验

    下面是小实验案例 // 0 if(undefined) { console.log('1'); } else { console.log('0'); } // 0 if(null) { console ...

  4. 深入贯彻闭包思想,全面理解JS闭包形成过程

    谈起闭包,它可是JavaScript两个核心技术之一(异步和闭包),在面试以及实际应用当中,我们都离不开它们,甚至可以说它们是衡量js工程师实力的一个重要指标.下面我们就罗列闭包的几个常见问题,从回答 ...

  5. javascript深入理解js闭包

    一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量 ...

  6. 深入理解JS闭包

    一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量 ...

  7. 通俗易懂的深入理解js闭包

    闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. 一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域 ...

  8. 理解js闭包(二)

    @(编程) 一.什么是闭包? 官方"的解释是:闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分. 相信很少有人能直接看懂这句话,因为他 ...

  9. javascript深入理解js闭包[转]

    一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量 ...

随机推荐

  1. IT兄弟连 JavaWeb教程 AJAX中参数传递问题

    使用Ajax发送GET请求并需要传递参数时,直接在URL地址后拼接参数,格式如下: xhr.open('get','请求路径?参数名1=参数值1&参数名2=参数值2...',true); 使用 ...

  2. python入门的基本历程

    Python入门 1.1环境安装 python官网下载,安装之后添加环境变量. 1.2集成开发环境 PyCharm官网下载,安装后:new project-﹥pure python 设置python解 ...

  3. 跟踪记录ABAP对外部系统的RFC通信

    对SAP系统而言,RFC最常见的系统间通信方式,SAP与SAP系统及SAP与非SAP系统之间的连接都可以使用它.它的使用便利,功能强大,在各种接口技术中,往往是最受(ABAP开发者)青睐的选择. 查询 ...

  4. java基础笔记(三)——main方法

    1.解析public static void main(String[] args)方法 JVM在运行程序时,会首先查找main()方法作为入口,main是JVM识别的特殊方法名. public是权限 ...

  5. nutzboot 使用nacos替换zookeeper

    先放一段从网上拷贝一段分布式CAP理论的概念 分布式领域中存在CAP理论,且该理论已被证明:任何分布式系统只可同时满足两点,无法三者兼顾. ①C:Consistency,一致性,数据一致更新,所有数据 ...

  6. ms sqlserver 清除数据库日志脚本

    USE [master] GO ALTER DATABASE F360DW SET RECOVERY SIMPLE WITH NO_WAIT GO ALTER DATABASE F360DW SET ...

  7. SSIS连接-左外连接

    应用场景: 当有多个数据源时,可能是在不同的数据库,或者是一个数据源来自数据库,另一个来自excel文件,想要把他们合并,像sql的左外联接时,应用到 源1: select 'A01' GoodsNo ...

  8. 重置 linux系统后要配置的基本组件操作

    1.安装jdk https://www.cnblogs.com/shihaiming/p/5809553.html 2.安装mysql 3.安装tomcat

  9. .md文件插图片,不建议使用绝对地址。

    一 主要有两种方法,一种绝对地址,一种相对地址. 而百度的话,全都是说绝对地址的. 但是,有很大的弊端啊 orz 二 先说绝对地址 ![image](https://github.com/AngelS ...

  10. vuex填坑记录

    vuex是需要等待页面加载完成后才会更新的,如果页面点击刷新有用到vuex的地方,那么vuex会保持旧的数据,等刷新完成后vuex的数据才会重置,所以要在页面加载后再调用vuex的数据才是正确的,如果 ...