了解了预编译和作用域的相关知识以后我们来看一下开发中常见的工具——闭包。还是来看一个实例。

 function a(){
function b() {
var bb=;
console.log(aa);
}
var aa=;
return b;
}
var dome = a();
dome();

我们来看一下上边的实例,首先我们在全局中定义了一个a函数,定义了一个变量dome等于a函数的执行。a执行就会产生一个自己执行期上下文(AO,activation object),存在作用域链的最顶端。a函数的执行产生了b函数的定义。所以b函数定义拿到a函数的AO。再往下看,并没有b函数的执行,它一直等着被执行,b函数现在的[[scope]]对象和a函数执行时的[[scope]]对象是一样的。如下图所示:

                                   

将上边两个图合成一个图:

当return b;语句执行完之后,a函数才算是执行完。既然a函数执行完了,a.[[scope]]中的AO就会被释放。但是在释放之前发生了一件惊天动地的事情。它把b函数保存到了外部去了。由全局变量dome来接收。这时候dome就是b函数,b函数就被保存到了外部,此时a函数执行完毕。a函数虽然释放了自己的AO,但是b函数还拿着a函数的AO。

注意:函数执行完之后并不意味着它的AO被破坏了,而是[[scope]]与AO的关联关系断了。如下图所示:

接着我们执行dome,也就是b,b函数是在a函数内部生成,而在全局被执行,我们看会发生什么?

首先b函数还是生成自己的AO放在作用域链的最顶端。如下图所示:

从视觉的角度上看好像是在b函数中访问不到aa变量,但其实在b函数中执行到console.log(aa); 系统就会沿着作用域链的最顶端去找变量aa,查找第0位b函数的AO中,没有aa,继续向下找,第一位a函数的AO中找到了aa:123,所以打印结果就为123。

像以上这种内部的函数被保存在了外部这个过程就是闭包。我们初步的认识了闭包可以自己思考一下下边的代码执行结果:

function a(){
var num = 100;
function b() {
num++;
console.log(num);
}
return b;
}
var dome = a();
dome();
dome();

Javascript的闭包(上)的更多相关文章

  1. 深入理解JavaScript的闭包特性如何给循环中的对象添加事件

    初学者经常碰到的,即获取HTML元素集合,循环给元素添加事件.在事件响应函数中(event handler)获取对应的索引.但每次获取的都是最后一次循环的索引.原因是初学者并未理解JavaScript ...

  2. JavaScript作用域闭包简述

    JavaScript作用域闭包简述 作用域 技术一般水平有限,有什么错的地方,望大家指正. 作用域就是变量起作用的范围.作用域包括全局作用域,函数作用域以块级作用域,ES6中的let和const可以形 ...

  3. 深入理解javascript的闭包

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

  4. 如何给循环中的对象添加事件--深入理解JavaScript的闭包特性

    初学者经常碰到的,即获取HTML元素集合,循环给元素添加事件.在事件响应函数中(event handler)获取对应的索引.但每次获取的都是最后一次循环的索引.原因是初学者并未理解JavaScript ...

  5. javascript,jquery(闭包概念)(转)

    偶尔听人说javascript闭包,让我联想起以前学编译原理和数字逻辑里讲的闭包,以前上课讲的闭包很难懂,而且含有递归的意思在里面,现在不想再查看里面的闭包概念. 但javascript我是经常要用, ...

  6. 理解Javascript 的闭包(closure)

    要理解闭包的概念先从变量的作用域说去 一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之 ...

  7. 两个示例介绍JavaScript的闭包

    JavaScript的闭包有两个用途:一个是访问函数内部的变量:另一个是让变量的值在作用域内保持不变.函数是JavaScript 中唯一有作用域的对象,因此JavaScript的闭包依赖于函数实现,下 ...

  8. 理解 Javascript 的闭包

    什么是闭包 闭包是什么?闭包是Closure,这是静态语言所不具有的一个新特性.但是闭包也不是什么复杂到不可理解的东西,简而言之,闭包就是: 闭包就是函数的局部变量集合,只是这些局部变量在函数返回后会 ...

  9. javascript 关于闭包的知识点

    javascript 关于闭包的认识 概念:闭包(closure)是函数对象与变量作用域链在某种形式上的关联,是一种对变量的获取机制. 所以要大致搞清三个东西:函数对象(function object ...

  10. 深入理解JavaScript的闭包特性 如何给循环中的对象添加事件(转载)

    原文参考:http://blog.csdn.net/gaoshanwudi/article/details/7355794 初学者经常碰到的,即获取HTML元素集合,循环给元素添加事件.在事件响应函数 ...

随机推荐

  1. Mybatis映射文件中的标签的使用

    <foreach> <!-- foreach --> <delete id="delMulti" parameterType="java.u ...

  2. javascript高级程序设计学习历程

    第三章 基本概念 3.1 语法 3.1.1 区分大小写 ECMAScript中的一切(变量,函数,操作符)都区分大小写的 3.1.2 标识符 标识符:变量,函数,属性的名字以及函数的参数. 标识符的命 ...

  3. nginx rewrite模块

    return 从0.8.42版本开始, return 语句可以指定重定向 url (状态码可以为如下几种 301,302,303,307), 也可以为其他状态码指定响应的文本内容,并且重定向的url和 ...

  4. 6 Linux用户和用户组管理

    Linux系统是一个多用户多任务的分时操作系统,任何一个要使用系统资源的用户都必须首相像系统管理员申请账号,然后以这个账号身份进入系统 每个用户账号都拥有一个唯一的用户名和各自的口令 用户在登陆时键入 ...

  5. RMAN笔记

    Rman常用命令 Preview选项 1)    显示用于还原system表空间数据文件的备份文件 RMAN> restore datafile 2 preview; 2)    显示用于还原特 ...

  6. linux 下按照文件名模糊查找文件

    fnmatch int fnmatch(const char *pattern, const char *string, int flags); 参数说明 FNM_NOESCAPE 如果这个标志设置了 ...

  7. alpine基础镜像使用

    关于Alpine的相关知识,可以参考下边的链接 https://yeasy.gitbooks.io/docker_practice/content/cases/os/alpine.html 一. al ...

  8. 【转】Pandas学习笔记(二)选择数据

    Pandas学习笔记系列: Pandas学习笔记(一)基本介绍 Pandas学习笔记(二)选择数据 Pandas学习笔记(三)修改&添加值 Pandas学习笔记(四)处理丢失值 Pandas学 ...

  9. Django中ModelViewSet的应用

    ModelViewSet源码 class ModelViewSet(mixins.CreateModelMixin, mixins.RetrieveModelMixin, mixins.UpdateM ...

  10. CentOS7.5下实现MySQL5.7主从同步

    这里使用两台Linux主机(一台充当MySQL主服务器,另一台充当MySQL从服务器),MySQL用yum安装,版本均为5.7,下表是它们所使用的操作系统以及IP地址. 两台Linux主机所使用的操作 ...