接触javascript很久了,每次理解闭包都似是而非,最近在找Web前端的工作,所以需要把基础夯实一下。

本文是参照了joy_lee的博客 闭包 在她这篇博客的基础上以批注的形式力争把我的理解阐述出来,如果有不当之处,欢迎批评指正。

《高级程序设计》上,这样说:当在函数内部定义了其他函数时候,就创建了闭包。闭包有权访问包含函数内部的所有变量。

(这句话怎么理解呢?照这句话理解的话,闭包就是一个嵌套函数嘛!嵌套函数对包含它的函数的变量当然可以访问,这是没有问题的。)

一般来说,内部函数是能够访问到上一级乃至全局的的变量的,那么就有人这样理解:通过闭包,可以实现外部访问函数局部内的变量。

(如果我们把作用域简单的分个级的话,假设全局作用域作为第一级,其中定义的函数体内部作用域作为第二级,在第二级作用域内嵌套定义的函数体内部作用域作为第三级,....等等,传统意义上,第一级不能访问第二级的变量(这种变量叫做局部变量),第二级不能访问第三级,...,而反过来是可以的,这就是作用域链。本级作用域内找不到再到上一级找,直至第一级全局。而闭包这种机制可以在第一级作用域中通过第三级作用域引用到第二级作用域中的变量,而方法就是在第二级作用域向第一级作用域返回拥有第三级作用域的函数引用。 这个引用才是关键,因为这个引用的存在,相关的第三作用域与第二作用域都成了这个引用运行的上下文,迫使垃圾回收机制GC不能回收这条链上所占用的资源。而如果没有这个引用,则跟一般函数一样,函数运行完资源就会被回收。而我的疑惑也在于此,闭包单指函数中的嵌套函数还是指被第一级引用了的嵌套函数?还是都是?还是说闭包并不是嵌套函数而是嵌套函数被第一级作用域引用时所形成的这种机制?)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function a(){
  
   var i=0;
  
  function b(){
  
     alert(++i);
  
    }
  
   return b;
  
 }
  
 var c = a();
  
 c();

即,闭包的作用就是在a执行完并返回后,闭包使得Javascript的垃圾回收机制GC不会收回a所占用的资源,因为a的内部函数b的执行需要依赖a中的变量。

由于闭包的存在使得函数a返回后,a中的i始终存在,这样每次执行c(),i都是自加1后alert出i的值。

那么,如果a不返回函数b,情况就完全不同了。因为a执行完后,b没有被返回给a的外界,只是被a所引用,而此时a也只会被b引用,因此函数a和b互相引用但又不被外界打扰(被外界引用),函数a和b就会被GC回收。

实际上是就是闭包延长变量的生命周期。通常函数的作用域即变量会在函数执行结束后被销毁,但当函数返回一个闭包,只要闭包不被释放,整条作用域链都会占用内存。(闭包延长变量的生命周期,这是指被第一级引用的情况。但如果没有这个引用,闭包还能称其为闭包吗?)

说道作用域链:即 函数自己的作用域、上一层的函数的作用域....和全局作用域。访问一个变量时,自己的没有,就一层层往上找,直至全局,若还没有,就报错。

(很想吐槽一句,闭包的作用域链是弯的。)

PS: 有网友推荐了另一篇文章javascript闭包概念简单解析,是不是权威暂且不提,总算有一个明确的概念:

说了这么多,闭包到底是什么,下面做一下总结:

闭包是一个概念,它描述了函数执行完毕内存释放后,依然内存驻留的一个现象,只要把握这个核心概念,闭包就不难理解了。

以上这篇让你一句话理解闭包(简单易懂)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

【repost】让你一句话理解闭包(简单易懂)的更多相关文章

  1. JavaScript——以简单的方式理解闭包

    闭包,在一开始接触JavaScript的时候就听说过.首先明确一点,它理解起来确实不复杂,而且它也非常好用.那我们去理解闭包之前,要有什么基础呢?我个人认为最重要的便是作用域(lexical scop ...

  2. 从执行上下文(ES3,ES5)的角度来理解"闭包"

    目录 介绍执行上下文和执行上下文栈概念 执行上下文 执行上下文栈 伪代码模拟分析以下代码中执行上下文栈的行为 代码模拟实现栈的执行过程 通过ES3提出的老概念-理解执行上下文 1.变量对象和活动对象 ...

  3. javascript深入理解闭包

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

  4. javascript深入理解闭包(转)

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

  5. js深入理解"闭包"

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

  6. JavaScript 从闭包可以做什么开始,将有助于理解闭包

    本文内容 函数内部访问全局变量 函数外部不能直接访问局部变量 函数外部访问局部变量 保护私有成员 持久性 模块化 抽象性 闭包是 JavaScript 的重要特性,非常强大,可用于执行复杂的计算,可并 ...

  7. javascript花式理解闭包

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

  8. js 理解闭包

    学习Javascript闭包(Closure) 引用: 阮一峰 http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures. ...

  9. javascript javascript面向对象的理解及简单的示例

    javascript面向对象的理解及简单的示例 零.本节重点: 1.封装: 2.继承: 壹.下面理解: 一. javascript面向对象概念: 为了说明 JavaScript 是一门彻底的面向对象的 ...

随机推荐

  1. mysql Table 'user' is marked as crashed and should be repaired

    myisamchk -f x:\xxxxxxxxx\MySQL\data\mysql\*.MYI

  2. windows搭建zabbix agent

    1.下载和解压zabbix agent 地址: http://www.zabbix.com/downloads/2.4.4/zabbix_agents_2.4.4.win.zip解压:conf目录存放 ...

  3. Python开发【第十篇】:Redis

    缓存数据库介绍 NoSQL(Not Only SQL),即"不仅仅是SQL",泛指非关系型的数据库.随着互联网web2.0网站的兴起,传统的关系数据库在应对web2.0网站,特别是 ...

  4. Junit集成测试

    Spring4.x高级话题(七):Spring的测试 一. 点睛 测试是开发工作中不可缺少的部分,单元测试只针对当前开发的类和方法进行测试,可以简单通过模拟依赖来实现,对运行环境没有依赖:但是仅仅单元 ...

  5. synchronized 同步函数的竞争关系验证

    synchronized是Java中的关键字,是一种同步锁.它修饰的对象有以下几种: 1. 修饰一个代码块,被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象是调用这个代码 ...

  6. Day1数据结构和算法

    2019-02-27 程序设计=数据结构+算法 数据结构就是关系,是数据元素相互之间存在的关系集合 逻辑结构:数据对象中数据元素的相互关系 集合结构:集合里的数据元素除了同属于一个集合外没有其他关系 ...

  7. 通过decorators = [,] 的形式给类中的所有方法添加装饰器

    给类添加装饰器有多种方法: 1.可以在类中的某个方法上边直接@添加,这个粒度细.无需详细介绍 2.也可以在类中通过 decorators=[, ]的形式添加,这样的话,类中的所有方法都会被一次性加上装 ...

  8. xx星空面试题

    一面 1.什么是多态 实现原理? 2.什么是重载?class加载原理? 3.常用设计模式,简单介绍 4.看过哪些java的书?android的书? 5.动态注册静态注册 优缺点?静态注册函数如何被调用 ...

  9. SSM框架中各层的含义和联系

    一.pojo层 也有人称其为model.domain.bean等,pojo层是对应的数据库表的实体类. 二.1.持久层:Dao层(Mapper) Dao(Data access object)层,称为 ...

  10. Mysql必知必会 第三章 使用Mysql

    第三章 使用Mysql SQL语句和大小写 请注意,SQL语句不区分大小写,因此SELECT与select是相同的.同样,写成Select也没有关系.许多SQL开发人员喜欢对所有SQL关键字使用大写, ...