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

 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. Python学习笔记之测试函数

    11-1 城市和国家:编写一个函数,它接受两个形参:一个城市名和一个国家名.这个函数返回一个格式为City, Country 的字符串,如Santiago, Chile.将这个函数存储在一个名为cit ...

  2. Struts2处理(jQuery)Ajax请求

    1. Ajax     Ajax(Asynchronous JavaScript and XML,异步JavaScript和XML)时一种创建交互式网页应用的网页开发技术,它并不是一项新的技术,其产生 ...

  3. Flask模板渲染

    目录 Flask模板渲染 Jinja2模板引擎简介 模板 Jinja2 模板变量 变量 控制结构 宏,类似Python代码中的函数 模板继承 包含(Include) 过滤器 链式调用 常见内建过滤器 ...

  4. i春秋——“百度杯”CTF比赛 十月场——Vld(Vulcan Logic Dumper 、php opcode、sql 报错注入)

    打开题目看到提示 "do you know Vulcan Logic Dumper?" ,再查看源码看到"<!-- index.php.txt ?>" ...

  5. Canny算法检测边缘

    Canny算法是边缘检测的一个经典算法,比单纯用一些微分算子来检测的效果要好很多,其优势有以下几点: 边缘误检与漏检率低. 边缘定位准确,且边界较细. 自带一定的滤噪功能,或者说,对噪声的敏感度要比单 ...

  6. 【Java_基础】Java中强制类型转换

    首先,狭义上的强制类型转换指的是引用类型,且是父类向子类转换,这种转换只牵扯到引用名义类型的转换,具体的对象内存没有发生一点变化. 而基本类型的转换与此不同,其数据确实发生了变化.如果是基本类型和其包 ...

  7. Nginx+Mysql调优

    使用nginx实现反向代理作用,具备负载均衡的功能.     接受客户端的请求 | nginx(宿主机) | |-------------------| web1 web2 (客户机)   原理: 与 ...

  8. vuex中mapGetters的使用及简单实现原理

    一.项目中的mapGetters在Vue项目的开发过程中必然会使用到vuex,对vue项目公用数据进行管理,从而解决组件之间数据相互通信的问题,如果不使用vuex,那么一些非父子组件之间的数据通信将会 ...

  9. bootstrap ui样例

    http://demo.codedefault.com/demo/ui/theadmin/samples/invoicer/settings.html

  10. EXCEPTION_HIJACK(0xe0434f4e)异常的抛出过程

    样例工程 在VS2013里新建一个C#控制台工程,写下如下代码: using System; using System.Collections.Generic; using System.Linq; ...