[JavaScript学习]JavaScript闭包-匿名函数和函数的作用域链 - Web前端
作者:98wpeu发布时间:2026-08-27分类:网页前端技术浏览:4
在上一篇文章中我们介绍了"正则表达式-使用正则表达式的字符串对象方法",到此为止,正则表达式就学习到这里了。今天将继续学习其他知识:“JavaScript闭包-匿名函数和函数的作用域链”。

匿名函数
在理解JavaScript的闭包之前,我们有必要了解一下JavaScript中函数的执行顺序。我们前面说过,定义函数有多种方式,其中最常用的是下面的两种方式。
/* 定义函数的第一种方式 */
function fn1(){
alert("fn1");
}
/* 定义函数的第二种方式 */
var fn2 = function(){
alert("fn2");
}对于第一种定义函数的方式,我们称为函数声明。以这种方式声明的函数会在函数执行之前被加载到内存中,所以无论是在函数定义之前,还是在函数定义之后调用这个函数都不会报错。
对于第二种定义函数的方式,我们称为函数表达式。以这种方式定义的函数会先在内存中创建一块区域,之后通过一个fn2的变量来指向这块区域,这块区域的函数开始是没有名称的,这种函数就叫做匿名函数,也叫作拉姆达(lambda)函数。如果我们在创建函数之前调用fn2(),那么程序会报错。
函数的作用域链
在javascript中,当进行函数的调用时,会创建一个执行环境,并为每一个函数增加一个属性SCOPE,通过这个属性来指向一块内存,这块内存中包含有所有上下文的变量。当在某个函数中调用了新函数之后,新函数依然会有一个作用域来执行原来的函数的SCOPE和自己新增加的SCOPE,这样就形成了一个链式结构,这就是JavaScript中的作用域链。
每一个函数都有自己的执行环境。当执行流进入一个函数时,函数的环境就会被推入一个环境栈中。在函数执行完毕后,栈将它的环境弹出,把控制权交回给原来的执行环境。
作用域链的用途是保证对执行环境有权访问的所有变量和函数的有序访问。在作用域链的最前端始终是当前执行的代码所在的环境的变量对象。作用域链的下一个变量对象来自于包含环境,再下一个变量对象又来自于下一个包含环境,一直延续到全局执行环境。全局执行环境的变量对象始终是作用域链的最后一个对象。
上面的这几段话是什么意思呢?我们还是通过具体的例子和内存模型分析来讲解。先看下面的例子,下面的这个例子完成的功能是简单的交换color属性的颜色:
// 定义一个颜色属性
var color = "red";
// 定义显示颜色的方法
var showColor = function(){
console.info(this.color);
}
/* 定义一个交换颜色的函数 */
function changeColor(){
var anotherColor = "blue";
function swapColor(){
var temPColor = anotherColor;
anotherColor = color;
color = tempcolor;
}
swapColor();
}
// 调用交换颜色的函数来改变颜色
changeColor();
// 调用showColor()方法
showColor();我们来看上面的一段代码,代码中首先定义了一个颜色变量color,和一个用于打印颜色的方法showColor()。然后又定义了一个用于交换颜色的函数changeColor(),它的作用是将全局作用域中的颜色“red”修改为“blue”。注意在这个函数中是通过另外一个函数swapColor()来实现交换的。
再接下来,我们开始执行changeColor()函数。上面说到,JS在执行函数的时候,会创建一个执行环境,并为每一个函数增加一个属性SCOPE,通过这个属性来指向一块内存,这块内存中包含有所有上下文的变量。那么,在执行changeColor()函数的时候,内存模型应该如下图所示:

图中蓝色部分是changeColor()函数的作用域链,由于changeColor()的执行上下文是Window对象,所以它的作用域链的最高位指向的是全局作用域(golbal scope)。在我们的程序中,目前全局作用域中有color、showColor和changeColor这3个属性。
changeColor()作用域链的低位指向的是它自己的作用域。在changeColor()中,有anotherColor和swapColor2个属性。
接下来开始执行changeColor()函数,在函数内部又创建了一个swapColor()函数,创建之后立刻执行这个函数。此时的作用域链内存模型如下图所示:

同样,swapColor的作用域链的最顶端指向的是全局作用域,下一级指向的是包含它的changeColor函数的作用域,最后才是指向自己的作用域。
接着,swapColor函数开始执行,第一代码是var tempColor = anotherColor,它首先会在自己的作用域中查找是否有tempColor属性,根据上面的图我们可以看到,在swapColor的作用域中存在tempColor属性,于是它把tempColor的值由“red”修改为“blue”。
第二句代码是anotherColor = color,首先它也是先在swapColor的作用域中查找anotherColor属性,发现没有找到,它就会通过作用域链到上一级的changeColor作用域中去查找,找到之后将anotherColor属性由“blue”修改为“red”。
第三句代码是color = tempColor,属性查找的方法相同,首先在自己的作用域中查找,没有找到的话到上一级的作用域去查找。最终会在全局作用域中找到color属性,于是它将全局作用域中的color属性由“red”修改为“blue”。
最后,swapColor函数执行完毕之后,函数会被垃圾回收,同时changeColor函数也执行完毕,同样被垃圾回收。紧接着我们调用了showColor()方法,此时又会为该函数创建新的执行环境和作用域链。
在showColor的作用域链中有2个指向:顶层的全局作用域和它自己的作用域。在执行showColor函数的时候,它在自己的作用域中没有发现color属性,于是到上一级的全局作用域中查找,此时全局作用域中的color属性已经被修改为“blue”,所以程序最终会打印出的颜色是“blue”。
返回javascript教程主目录>>
相关推荐
- [JavaScript学习]JavaScript面向对象-基于原型链实现继承 - Web前端
- [JavaScript学习]正则表达式-常用正则表达式汇总(大全) - Web前端
- [JavaScript学习]正则表达式-什么是正则表达式? - Web前端
- [JavaScript学习]正则表达式-正则表达式的应用示例 - Web前端
- [JavaScript学习]JavaScript事件-DOM0级事件和DOM2级事件处理 - Web前端
- [JavaScript学习]JavaScript数据类型转换 - Web前端
- [JavaScript学习]正则表达式-正则表达式的元字符 - Web前端
- [JavaScript学习]JavaScript深入理解函数 - 函数的属性 - Web前端
- [JavaScript学习]JavaScript深入理解函数 - 函数的定义 - Web前端
- [JavaScript学习]JavaScript文档对象模型-DOM2级样式 - Web前端
- 网页前端技术排行
-
- 1[Web前端]用javascript实现默认图片替代未显示的图片 - Web前端
- 2分析Iconfont-阿里巴巴矢量常用图标库 - Web前端
- 3jQuery实例教程:制作网页中可折叠的面板 - Web前端
- 4【第六章】Foundation之按钮和下拉功能 - Web前端
- 5基于jquery的滚动条滚动固定div(附演示下载) - Web前端
- 6jQuery编写widget的一些技巧分享 - Web前端
- 7分享精心挑选的12款优秀jQuery Ajax分页插件和教程 - Web前端
- 8jQuery实现鼠标移到元素上动态提示消息框效果 - Web前端
- 9在Mac/PC上远程调试iPhone/iPad上的网页 - Web前端
- 最近发表
-
- WordPress随机显示特色图片插件:Random Post Thumbnails
- KeePass实现Chrome浏览器自动填充密码方法一
- LNMP一键包nginx 301强制跳转到https教程
- KeePass实现Chrome浏览器自动填充密码方法二
- #建站# 免费的VPS管理软件Xshell8/Xftp8中文版下载
- 使用Xshell 8连接VPS教程_电脑登录vps的方法
- WordPress评论界面添加烟花????效果
- 不同浏览器书签同步方案:坚果云+Floccus_详细使用教程
- iOS端KeePassXC客户端APP:Strongbox Password Safe
- 给WordPress评论中的Gravatar头像图片添加ALT属性


