JavaScript闭包理解的关键 - 作用域链
阮一峰的一篇文章已经对闭包的用途、概念讲解地相对清晰了。
闭包就是能够读取其他函数内部变量的函数。
但我认为里面对于作用域链的解释还不够清晰,这里作一些补充。
闭包之所以可以读取外部函数的内部变量,即使外部函数已经返回,是因为它把外部函数的活动对象加到了自己的作用域链中。
而理解作用域对于完全理解闭包很重要。
作用域链是什么?
对于这段代码
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闭包理解的关键 - 作用域链的更多相关文章
- 深入理解JS函数作用域链与闭包问题
function fun(n,o) { console.log(o) return { fun:function(m){ return fun(m,n); } }; } ); a.fun(); a.f ...
- 对于 Javascript 闭包理解
一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量 ...
- javascript 闭包理解
摘自:http://www.cnblogs.com/jkswjw/p/3180384.html javascript 闭包基础分享 闭包向来给包括JavaScript程序员在内的程序员以神秘,高深的感 ...
- javascript闭包理解
//闭包理解一 function superFun(){ var _super_a='a'; function subfuc(){ console.log(_super_a); } return su ...
- JavaScript闭包理解【关键字:普通函数、变量访问作用域、闭包、解决获取元素标签索引】
一.闭包(Closure)模糊概述 之前总觉得闭包(Closure)很抽象而且难理解,百度一下"闭包"名词,百度的解释是:“闭包是指可以包含自由(未绑定到特定对象)变量的代 ...
- JavaScript ——闭包理解
昨天晚上听别人谈起闭包这个东西,虽然对js有一点了解但却丝毫没有印象,今天也没什么事就顺便研究了一下满足好奇宝宝.整合于网上的理解,记录一下. 一.闭包的作用域 要理解闭包,首先必须理解Javascr ...
- 关于javascript闭包理解
闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. 一:关于变量的作用域 Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量. ...
- JavaScript闭包理解【关键字:普通函数、闭包、解决获取元素标签索引】
以前总觉得闭包很抽象,很难理解,所以百度一下"闭包"概览,百度的解释是:“闭包是指可以包含自由(未绑定到特定对象)变量的代码块:这些变量不是在这个代码块内或者任何全局上下文中定义的 ...
- javascript 闭包理解例子
function Jquery(){ this.name = 'ysr'; this.sex = 'man'; return { x: this, age : 26 } } var b = new J ...
随机推荐
- 【转】说说JSON和JSONP,也许你会豁然开朗,含jQuery用例
由于Sencha Touch 2这种开发模式的特性,基本决定了它原生的数据交互行为几乎只能通过AJAX来实现. 当然了,通过调用强大的PhoneGap插件然后打包,你可以实现100%的Socket通讯 ...
- 排序算法——交换排序(冒泡排序、快速排序)(java)
一.冒泡排序 时间复杂度:O(n^2) 公认最慢的排序,每次把最大/最小的放一边,原理: [57,68,59,52] [57,68,59,52] [57,59,68,52] [57,59,52,68] ...
- 一周学会Mootools 1.4中文教程:(6)动画
先看一下动画的参数设置: 参数: fps - (number:默认是50) 每秒的帧数. unit - (string:默认是 false) 单位,可为 'px','em',或 '%'. link - ...
- FileInputStream(字节流)与fileReader(字符流) 的区别
FileInputStream 类 1 ) FileInputStream 类介绍: 以字节为单位的流处理.字节序列:二进制数据.与编码无关,不存在乱码问题. FileInputStream 类的主要 ...
- 拦截API 注入进程
本文详细的介绍了在Visual Studio(以下简称VS)下实现API钩子的编程方法,阅读本文需要基础:有操作系统的基本知识(进程管理,内存管理),会在VS下编写和调试Win32应用程序和动态链接库 ...
- python+sublime text2中文乱码[Decode error - output not utf-8]
转自: http://blog.sina.com.cn/s/blog_765abd7b0101dtbw.html 学习,记录一下.中文编码真的挺麻烦.抽空把自己的sb3的配置写一些. 该问题让我纠结了 ...
- 数字运算、ASCII
num20 = dollar/20;num10 = (dollar - 20*num20)/10;num5 =(dollar-20*num20-10*num10)/5;//可以写为num5 = (do ...
- Mac使用技巧
外接显示器的生活,在 系统偏好设置--显示器--排列中,点击那个白色的条,可以设置主显示器.
- POJ 1700 经典过河问题(贪心)
POJ题目链接:http://poj.org/problem?id=1700 N个人过河,船每次最多只能坐两个人,船载每个人过河的所需时间不同,问最快的过河时间. 思路: 当n=1,2,3时所需要的最 ...
- 实习生的Django[1]
尽管学期尚未结束,暑假尚未到来,可是大三的同学非常多已经和我一样開始实习或者实习一段时间了.我仅仅面试了一间数据挖掘的公司的研发部,还算顺利通过. 来这里实习后,由于网络原因,昨天没有刷题也没有写BL ...