阮一峰的一篇文章已经对闭包的用途、概念讲解地相对清晰了。

闭包就是能够读取其他函数内部变量的函数。

但我认为里面对于作用域链的解释还不够清晰,这里作一些补充。

闭包之所以可以读取外部函数的内部变量,即使外部函数已经返回,是因为它把外部函数的活动对象加到了自己的作用域链中。

而理解作用域对于完全理解闭包很重要。

作用域链是什么?

对于这段代码

    function compare(value1,value2){
alert("this "+this+" arguments "+arguments);
if(value1 < value2){
return -1;
}else if( value1 > value2){
return 1;
}else{
return 0;
}
} var result = compare(5,10);

JavaScript高级程序设计里这样写

在创建函数compare()时,会创建一个预先包含全局变量的作用域链,当调用时,会为函数创建一个执行环境。

其作用域链中包含两个变量对象:本地活动对象和全局变量对象。

作用域链本质上是一个指向变量对象的指针列表。

画出来大概是这个样子的

举个闭包的例子

    var name = "the window";

    var object = {
name: "My Object",
getNameFunc: function(){
return function () {
return this.name;
}
}
}

很多人不明白为什么this.name不指向包含函数中的object.name。

对于这个问题,同样是这本书中有一句话

每个函数被调用时都会自动取得两个特殊变量:this 和 arguments。内部函数在搜索这两个变量时,只会搜索到其活动对象为止。

意思是,匿名函数的this是按作用域链搜索的,当在匿名函数本身的活动对象中就找到this后,就不会再向外搜索了。this指向的活动对象中并没有name属性,所以指向了全局的this。

作用域链画出来是这样的

现在明白了吧,闭包之所以有这样的表现,是因为搜索标识符时按照作用域链,从内向外搜索。

再看下这个例子你会更清楚。

    var name = "the window";

    var object = {
name: "My Object",
getNameFunc: function(){
var that = this;
return function () {
alert("that "+that);
return that.name;
}
} }

变化在于这里

匿名函数在自身的活动对象里没找到that对象,就沿作用域链向上找,在getNameFunc()的活动对象里找到了that,指向的就是this。

所以你可以按F12自己测试一下,输出结果是"My Object"

JavaScript闭包理解的关键 - 作用域链的更多相关文章

  1. 深入理解JS函数作用域链与闭包问题

    function fun(n,o) { console.log(o) return { fun:function(m){ return fun(m,n); } }; } ); a.fun(); a.f ...

  2. 对于 Javascript 闭包理解

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

  3. javascript 闭包理解

    摘自:http://www.cnblogs.com/jkswjw/p/3180384.html javascript 闭包基础分享 闭包向来给包括JavaScript程序员在内的程序员以神秘,高深的感 ...

  4. javascript闭包理解

    //闭包理解一 function superFun(){ var _super_a='a'; function subfuc(){ console.log(_super_a); } return su ...

  5. JavaScript闭包理解【关键字:普通函数、变量访问作用域、闭包、解决获取元素标签索引】

        一.闭包(Closure)模糊概述 之前总觉得闭包(Closure)很抽象而且难理解,百度一下"闭包"名词,百度的解释是:“闭包是指可以包含自由(未绑定到特定对象)变量的代 ...

  6. JavaScript ——闭包理解

    昨天晚上听别人谈起闭包这个东西,虽然对js有一点了解但却丝毫没有印象,今天也没什么事就顺便研究了一下满足好奇宝宝.整合于网上的理解,记录一下. 一.闭包的作用域 要理解闭包,首先必须理解Javascr ...

  7. 关于javascript闭包理解

    闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. 一:关于变量的作用域 Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量. ...

  8. JavaScript闭包理解【关键字:普通函数、闭包、解决获取元素标签索引】

    以前总觉得闭包很抽象,很难理解,所以百度一下"闭包"概览,百度的解释是:“闭包是指可以包含自由(未绑定到特定对象)变量的代码块:这些变量不是在这个代码块内或者任何全局上下文中定义的 ...

  9. javascript 闭包理解例子

    function Jquery(){ this.name = 'ysr'; this.sex = 'man'; return { x: this, age : 26 } } var b = new J ...

随机推荐

  1. hadoop搭建杂记:Linux下虚拟机集群网络搭建

    VirtualBox搭建hadoop伪分布式模式 VirtualBox搭建hadoop伪分布式模式 master: ip:192.168.56.120 机器名: master 启动NameNode 启 ...

  2. 解决全站ie6下PNG图片不透明问题只要几行代码

    解决全站ie6下PNG图片不透明问题只要复制下面这几行代码粘贴在你的文档最底部,需要用到的包DD_belatedPNG_0.0.8a.js自己网上下载吧 代码走起 /*在文档底部加入以下代码*/ &l ...

  3. codeforces 650D. Zip-line 线段树

    题目链接 题目的意思很简单, 就是给你n个数, m个询问, 每次询问修改某一个位置的值, 然后问你修改完之后数列的lis是多少. 询问独立. 对于原数列, 我们将它离散化, 令dp1[i]为以i为结尾 ...

  4. MVC进阶之路:依赖注入(Di)和Ninject

    MVC进阶之路:依赖注入(Di)和Ninject 0X1 什么是依赖注入 依赖注入(Dependency Injection),是这样一个过程:某客户类只依赖于服务类的一个接口,而不依赖于具体服务类, ...

  5. Maven 添加Jetty

        <build>         <finalName>springmvc</finalName>         <plugins>       ...

  6. SQLServer 2008的组成

    SQLServer 2008的组成: 1.主要数据库文件:有且只有一个,文件后缀为.mdf. 2.日志文件:至少有一个,文件后缀为.ldf. 3.次要数据库文件:任意个,文件后缀为.ndf.

  7. iOS 按钮倒计时功能

    iOS 按钮倒计时功能, 建议把按钮换成label,这样会避免读秒时闪烁 __block ; __block UIButton *verifybutton = _GetverificationBtn; ...

  8. Javascript高级程序设计学习笔记一

    看完w3school的javascript的概念,有点基础,开始红皮书的路程,今晚总结前二章的心得. 第一章:javascript简介 重点是javascript的实现是由 ECMAScript(核心 ...

  9. Oracle 局域网布置数据库服务器,客户端连接提示TNS:无监听器的解决实现

    Oracle布置在局域网中的服务器的时候,用本地PL SQL 链接没有丝毫的问题. 但是,如果用远程客户端的PL SQL 链接的时候却出现了“TNS:无监听器”的问题. 首先,就是进行了服务器端的监听 ...

  10. IOS学习之蓝牙4.0

    1建立中心角色 1 2 3 #import <CoreBluetooth/CoreBluetooth.h>  CBCentralManager *manager;  manager = [ ...