学习 JavaScript 的同学都会面对闭包,总觉得很难,你会看到闭包各种版本的定义,即使把闭包的概念背会也不一定的能够理解闭包。想要掌握闭包,需要看很多关于闭包的资料,加上对 JavaScript 执行过程的理解才能掌握闭包。如果你看到“一文读懂闭包”,“十分钟读懂闭包”这类文章后,想「投机取巧」花几分钟时间能够理解闭包,其实是不可能的,一切需要脚踏实地,慢慢就理解了。

「闭包的出现能给编程带来哪些便捷呢?」,这是我们学习闭包首先需要面对的问题,也就是说闭包出现的背景是什么。

函数是无状态的,比如下面的函数:

function call() {var name = 'suyan';var age = 20;console.log(name + ' age is ' + age);
}
call();

当 call 函数执行完后 name 和 age 占用的内存空间将会被释放,在函数外部无法访问变量 name 和 age 。如果想要在函数 call 外访问变量 age,且函数执行完后保留 age 的值,咋么办?

想要解决这个问题,可以使用闭包(colsure)

function call() {var name = 'suyan';var age = 20;console.log(name + ' age is ' + age);return {getAge: function () {return age;},setAge: function (newValue) {age = newValue;}};
}
const ageObj = call();
console.log(ageObj.getAge()); // 20
// 修改 age 的值为 30
ageObj.setAge(30);
console.log(ageObj.getAge()); // 30

通过 Chrome 调试工具可以查看 call 这个函数捕获的闭包中的变量:

闭包一大重要特征就是可以「保存函数执行环境中的变量」,使其延迟释放,比如下面的函数:

function createCounter() {let counter = 0;const myFunction = function() {counter = counter + 1;return counter;};return myFunction;
}
// increment 是一个函数
const increment = createCounter();
const c1 = increment();
const c2 = increment();
const c3 = increment();
console.log(c1, c2, c3); // 1,2,3

increment 这个函数使用了 createCounter 中的变量 counter,每次调用 increment 这个函数,变量 counter 一直保存在执行环境中,并不会被释放。再创建一个 increment2,这是 c11 的值为 1。可见 increment 和 increment2 使用的执行环境互不影响。

const increment2 = createCounter();
const c11 = increment2();
console.log(c11); // 1

闭包使得一个函数可以访问另一个函数作用域中的变量。我们在看一下 JavaScript 内置对象数组 这节课程中的一道关于闭包的面试题:

(function () {var numbers = [];for (var i = 0; i < 4; i++) {numbers.push(function () {return i;});}var result = numbers.map(function (e) {return e();});console.log(result); // 值是什么?
})();
‍

最终打印的值是 4、4、4、4。在函数中通过 var 声明的变量 i 属于函数作用域,当代码执行到第 8 行后, i 的值是 4。此时 numbers 中保存为 4 个函数,当这些函数被执行的时候会使用当前函数执行环境中的变量 i,此时值为 4,故最终 result 中的值都是 4。

如果把上面代码中的 var i = 0;修改成 let i = 0;结果是什么?

总之,闭包可以延长变量的释放,你可以把闭包看做是带有执行环境的函数。


推荐阅读:

看透变量提升与块级作用域实现的原理
执行上下文与调用栈
推荐我精心准备的 JavaScript 学习资源

带有执行环境的函数 - 闭包相关推荐

  1. js执行环境作用域和闭包_JavaScript中执行上下文,提升,作用域和闭包的终极指南

    js执行环境作用域和闭包 It may seem surprising, but in my opinion the most important and fundamental concept to ...

  2. 深入理解闭包系列第二篇——从执行环境角度看闭包

    前面的话 本文从执行环境的角度来分析闭包,先用一张图开宗明义,然后根据图示内容对代码进行逐行说明,试图对闭包进行更直观的解释 图示 说明 下面按照代码执行流的顺序对该图示进行详细说明 function ...

  3. 闭包、执行环境、作用域链

    闭包是指有权访问另一个函数作用域中的变量的函数,创建的常见方式就是在一个函数内部创建另一个函数. 我们来理解下执行环境和作用域链: 1.执行环境有全局执行环境和函数执行环境之分. 2.每次进入一个新的 ...

  4. JavaScript中的执行环境

    JavaScript中的执行环境 注意区分函数的执行环境和函数声明环境 看代码: 转载于:https://www.cnblogs.com/mc67/p/5190179.html

  5. 作用域、执行环境、作用域链

    作用域,之前有介绍过,JavaScript无块级作用域,只有函数作用域,简单点说就是JavaScript的作用域就是函数作用域.因为有函数作用域,所以我们有全局作用域和局部作用域的说法. 执行环境是什 ...

  6. JavaScript——执行环境、变量对象、作用域链

    前言 这几天在看<javascript高级程序设计>,看到执行环境和作用域链的时候,就有些模糊了.书中还是讲的不够具体.通过上网查资料,特来总结,以备回顾和修正. 目录: EC(执行环境或 ...

  7. JavaScript语言精粹--执行环境及作用域,this

    1.执行环境定义了变量或函数有权访问的其他数据,决定了他们各自的行为. 每个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保存在这个对象中. 虽然我们无法访问,但是解析器在处理数据时 ...

  8. JavaScript执行环境

    执行环境(Execution Context,也称为"执行上下文")是JavaScript中最为重要的一个概念.执行环境定义了变量或函数有权访问的其它数据,决定了各自的行为.当Ja ...

  9. JavaScript执行环境 + 变量对象 + 作用域链 + 闭包

    闭包真的是一个谈烂掉的内容.说到闭包,自然就涉及到执行环境.变量对象以及作用域链.汤姆大叔翻译的<深入理解JavaScript系列>很好,帮我解决了一直以来似懂非懂的很多问题,包括闭包.下 ...

最新文章

  1. 第一个python去掉行号
  2. Hadoop实例之利用MapReduce实现日志清洗(附源代码)
  3. 内容处理和分发中的算法应用探究
  4. Django 执行 makemigrations 显示 No changes detected in app
  5. Linux学习之系统编程篇:利用 shm 进行进程间通信
  6. 尝鲜.net core2.1 ——编写一个global tool
  7. 21 RadioGroup ListFragment
  8. LVM--逻辑卷管理
  9. python按月分组_python-将行按两列分组并通过比较过滤值
  10. 在Eclipse新建菜单中添加菜单项,其他地方添加菜单项类似
  11. axios, ajax和fetch的比较
  12. additemdecoration重复_安卓中另一个强大的大量数量集控件RecyclerView
  13. android中一些常用的VIEW动作类型
  14. Sybase ASE15.7静默安装
  15. 01_LBP算法原理
  16. Vijos P1423 最佳路线
  17. 卓有成效的管理者—第一章 卓有成效是可以学会的
  18. 嵌入式开发需要学习什么?
  19. centos查询 硬盘序列号查询_CentOS查看主板型号、CPU、显卡、硬盘等信息
  20. C++ 字元陣列(C-style)、字元指標、String類別 使用方式整理

热门文章

  1. 在Linux上搭建Socks5 Proxy代理服务器
  2. 如何将java集合中重复的元素取出来
  3. 初始化我的archlinux
  4. 关于后端数据无法显示在页面上的问题
  5. JAVA多线程模仿站台三个窗口同时出售20张票
  6. 第四章:商品治理五大策略
  7. 膜拜!用最少的代码却实现了最牛逼的滚动动画
  8. 电脑蓝牙打电话-总结(四、百瑞互联BRLink)
  9. [奥塔在线]JAVA启蒙:WIN10下的JDK环境部署
  10. 2021年高压电工考试报名及高压电工最新解析