刚刚总结完作用域链,我觉得很有必要马上对闭包总结一下,因为,之前也写过自己对闭包的理解,那时候只知道,闭包就是可以访问别的函数变量的函数,就是在函数里面的函数就叫做闭包,可是并没有深入探究,为什么,可以访问别的函数变量呢?直到,学习了JS的作用域链之后,就恍然大悟。

首先,来回顾一下,什么是作用域链吧。

作用域链就是由当前执行环境与上层环境的一系列变量对象组成,保证了当前执行环境对符合访问权限的变量和函数的有序访问。

那么什么是闭包呢?

闭包

关于闭包的定义,我在之前的文章里面已经讲过了,就是能够读取其它函数内部变量的函数,那么为什么闭包可以读取其它函数内部的变量呢?这里面就涉及到了作用域链。

demo01
var fn = null;
function foo(){
var a = 2;
function innerFoo(){
console.log(a);
}
fn = innerFoo();
}
function Bar(){
fn();
}
foo();
Bar();

在这个例子里面,正常来说,按照作用域链的规则,在foo()函数的内部innerFoo()函数可以访问到,父级foo()的属性和方法,还有全局作用域下的属性和方法。这是因为,在innerFoo()的作用域链里面包含了fooEC和globalEC的变量对象,所以有权限访问。

但是,之前讲过的垃圾回收机制提到,如果foo()方法执行完毕,应该释放内存,然后让垃圾回收机制回收,可是,为什么在Bar()里面依然能访问到fn()方法呢?

从上图可以看出,因为fn = innerFoo();这句语句,使得全局作用域下的变量fn保存了innerFoo()方法的引用,并且innerFoo()方法是依赖于foo()方法的,所以导致,foo()方法里面的局部变量都保存在了内存里面,没有被回收,这也是使用闭包不当的一个弊端,会导致内存泄漏。

当执行Bar()方法的时候,Bar()的作用域链中包含了全局作用域下的变量对象,所以可以访问到foo()方法下的innerFoo(),这就是闭包的一个底层原理。

JS进阶系列之闭包的更多相关文章

  1. 【 D3.js 进阶系列 】 进阶总结

    进阶系列的文章从去年10月开始写的,晃眼又是4个多月了,想在年前总结一下. 首先恭祝大家新年快乐.今年是羊年吧.前段时间和朋友聊天,聊到十二生肖里为什么没猫,我张口就道:不是因为十二生肖开会的时候猫迟 ...

  2. 【 D3.js 进阶系列 — 4.0 】 绘制箭头

    转自:http://www.ourd3js.com/wordpress/?p=660 [ D3.js 进阶系列 — 4.0 ] 绘制箭头 发表于2014/12/08 在 SVG 绘制区域中作图,在绘制 ...

  3. 【 D3.js 进阶系列 — 1.1 】 其它表格文件的读取

    CSV 表格文件是以逗号作为单元分隔符的,其他还有以制表符 Tab 作为单元分隔符的 TSV 文件,还有人为定义的其他分隔符的表格文件.本文将说明在 D3 中怎样读取它们. 1. TSV 表格文件是什 ...

  4. 【 D3.js 进阶系列 — 1.2 】 读取 CSV 文件时乱码的解决方法

    在 D3 中使用 d3.csv 读取 CSV 文件时,有时会出现乱码问题. 怎么解决呢? 1. 乱码问题 使用 d3.csv 读取 xxx.csv 文件时.假设 xxx.csv 文件使用的是 UTF- ...

  5. JS进阶系列之作用域链

    在之前写的进阶系列里面,提到了执行上下文在创建阶段,要创建变量对象.确定作用域链还有确定this的指向,本次将重点讲解一下作用域链. JavaScript代码的执行过程 在讲解作用域链之前,首先了解一 ...

  6. JS进阶系列之内存空间

    也许很多人像我一样,觉得JS有垃圾回收机制,内存就可以不管了,以至于在全局作用域下定义了很多变量,自以为JS会自动回收,直到最近,看了阮一峰老师,关于javascript内存泄漏的文章时,才发现自己写 ...

  7. 【 D3.js 进阶系列 — 6.1 】 缩放的应用(Zoom)

    缩放(Zoom)是另一种重要的可视化操作,主要是使用鼠标的滚轮进行. 1. zoom 的定义 缩放是由 d3.behavior.zoom() 定义的. var zoom = d3.behavior.z ...

  8. 【 D3.js 进阶系列 — 2.1 】 力学图的事件 + 顶点的固定

    本章讨论在力学图中经常使用到的事件( Event ),然后对[p=555">进阶 - 第 2.0 章]的人物关系图进行改进.使用户可以固定拖拽的对象. 在[入门 - 第 9.2 章]和 ...

  9. 【 D3.js 进阶系列 — 1.0 】 CSV 表格文件的读取

    在入门系列的教程中.我们经常使用 d3.json() 函数来读取 json 格式的文件.json 格式非常强大.但对于普通用户可能不太适合,普通用户更喜欢的是用 Microsoft Excel 或 O ...

随机推荐

  1. Linux磁盘分区和挂载

    Linux磁盘分区和挂载 分区 分区的方式: mbr分区 最多支持4个主分区 系统只能安装到主分区上 扩展分区要占用一个主分区 MBR最大支持2TB,但拥有最好的兼容性 gtp分区 支持无线多个主分区 ...

  2. iis7中session丢失的解决方法小结

    这篇文章主要介绍了在windows server 2008系统中,session丢失的解决方法,供大家学习参考 问题描述: Windows Server 2008 +IIS +ASP.net +SQL ...

  3. 443 D. Teams Formation

    http://codeforces.com/contest/879/problem/D This time the Berland Team Olympiad in Informatics is he ...

  4. scp 指定端口(转)

    1.注意-P 大写 2.实例 从服务器下载 scp -P 26399 root@104.222.133.88:/home/wwwroot/default/phpmyadmin/save/wordpre ...

  5. Linux下onvif客户端关于ipc摄像头的搜索

    设备搜索:要访问一个IPC摄像头,或者说要调用IPC摄像头提供的WEB服务接口,就要先知道其IP地址,这就是设备发现的过程,或者叫设备搜索的过程.IPC摄像头用的是239.255.255.250(端口 ...

  6. linux中服务环境的搭建

    一.Samba服务 samba服务的安装及配置: sudo apt-get install samba 二.配置: 1.创建一个需要共享的目录,并修改权限: lpf@ubuntu:~$ mkdir l ...

  7. python 3.x 循环读取文件用户登录

    import os # 导入python自带库的模块 import sys # 导入python自带库的模块 import getpass # 导入python自带库的模块 lock_file = ' ...

  8. 修复Gradle CreateProcess error=206

    插件地址:https://plugins.gradle.org/plugin/ua.eshepelyuk.ManifestClasspath 修复Window系统中Gradle 路径太长问题, Fix ...

  9. 兼容性/pollyfill/shim/渐进增强/优雅降级

    http://ued.ctrip.com/blog/browser-compatibility-testing-tools-in-firefox-compatibility-detector.html ...

  10. Python urllib模块学习

    urlopen()与urlretrieve() 1.urlopen()方法 urllib.urlopen(url[, data[, proxies]]) :创建一个表示远程url的类文件对象,然后像本 ...