学了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. Python基础:模块化来搭项目

    简单模块化 import 最好在最顶端 sys.path.append("..")表示把当前程序所在位置向上提了一级 在python3规范中,__init__.py并不是必须的. ...

  2. C# File和fileinfo类

    两个类功能差不多,File是静态方法实现的,Fileinfo通过实例方法实现的: 文件操作例子: using System; using System.Collections.Generic; usi ...

  3. ES6新特性使用小结(四)

    十一.Proxy .Reflect ①.Proxy 的概念和常用方法 { let obj = { //1.定义原始数据对象 对用户不可见 time: '2017-09-20', name: 'net' ...

  4. CSS3 - CheakBox 开关效果

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  5. MySQL存储过程多条修改语句

    DROP procedure Sel_Function_ActivityPastDueDELIMITER $$DROP procedure IF EXISTS`shouyi`.`Sel_Functio ...

  6. JsonModel&AFNetWorking

    // HttpManager.h // JsonModel&AFNetWorking // // Created by qianfeng on 15/7/21. // Copyright (c ...

  7. readonly与const的区别

    readonly 关键字与 const 关键字不同.const 字段只能在该字段的声明中初始化.readonly字段可以在声明或构造函数中初始化.因此,根据所使用的构造函数,readonly字段可能具 ...

  8. @PropertySource

    功能 加载指定的属性文件(*.properties)到 Spring 的 Environment 中.可以配合 @Value 和 @ConfigurationProperties 使用. @Prope ...

  9. python-day1作业(感谢视频老师留的作业)

    __author__ = 'zht' #!/usr/bin/env python # -*- coding: utf-8 -*- ''' #努力学习每一天 ''' #尝试次数计数器 tries = 0 ...

  10. 纪念Google Reader—Google Reader的最后一天

    从2006年到今天,几乎每天我都会打开Google Reader,但是今天不一样,因为它是最后一天.心情有些依依不舍,像是与一位多年老朋友永别.因此我非常痛恨Google,先给你送来个好朋友,再从你身 ...