0

0

JavaScript闭包-匿名函数和函数的作用域链

黄舟

黄舟

发布时间:2017-01-20 14:15:13

|

1689人浏览过

|

来源于php中文网

原创

 匿名函数

在理解javascript的闭包之前,我们有必要了解一下javascript中函数的执行顺序。我们前面说过,定义函数有多种方式,其中最常用的是下面的两种方式。

/* 定义函数的第一种方式 */
function fn1(){
  alert("fn1");
}
/* 定义函数的第二种方式 */
var fn2 = function(){
  alert("fn2");
}

对于第一种定义函数的方式,我们称为函数声明。以这种方式声明的函数会在函数执行之前被加载到内存中,所以无论是在函数定义之前,还是在函数定义之后调用这个函数都不会报错。

对于第二种定义函数的方式,我们称为函数表达式。以这种方式定义的函数会先在内存中创建一块区域,之后通过一个fn2的变量来指向这块区域,这块区域的函数开始是没有名称的,这种函数就叫做匿名函数,也叫作拉姆达(lambda)函数。如果我们在创建函数之前调用fn2(),那么程序会报错。

 函数的作用域链

在JavaScript中,当进行函数的调用时,会创建一个执行环境,并为每一个函数增加一个属性SCOPE,通过这个属性来指向一块内存,这块内存中包含有所有上下文的变量。当在某个函数中调用了新函数之后,新函数依然会有一个作用域来执行原来的函数的SCOPE和自己新增加的SCOPE,这样就形成了一个链式结构,这就是JavaScript中的作用域链。

每一个函数都有自己的执行环境。当执行流进入一个函数时,函数的环境就会被推入一个环境栈中。在函数执行完毕后,栈将它的环境弹出,把控制权交回给原来的执行环境。

立即学习Java免费学习笔记(深入)”;

作用域链的用途是保证对执行环境有权访问的所有变量和函数的有序访问。在作用域链的最前端始终是当前执行的代码所在的环境的变量对象。作用域链的下一个变量对象来自于包含环境,再下一个变量对象又来自于下一个包含环境,一直延续到全局执行环境。全局执行环境的变量对象始终是作用域链的最后一个对象。

上面的这几段话是什么意思呢?我们还是通过具体的例子和内存模型分析来讲解。先看下面的例子,下面的这个例子完成的功能是简单的交换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()函数的时候,内存模型应该如下图所示:

501.jpg

图中蓝色部分是changeColor()函数的作用域链,由于changeColor()的执行上下文是window对象,所以它的作用域链的最高位指向的是全局作用域(golbal scope)。在我们的程序中,目前全局作用域中有color、showColor和changeColor这3个属性。

动态WEB网站中的PHP和MySQL:直观的QuickPro指南第2版
动态WEB网站中的PHP和MySQL:直观的QuickPro指南第2版

动态WEB网站中的PHP和MySQL详细反映实际程序的需求,仔细地探讨外部数据的验证(例如信用卡卡号的格式)、用户登录以及如何使用模板建立网页的标准外观。动态WEB网站中的PHP和MySQL的内容不仅仅是这些。书中还提到如何串联JavaScript与PHP让用户操作时更快、更方便。还有正确处理用户输入错误的方法,让网站看起来更专业。另外还引入大量来自PEAR外挂函数库的强大功能,对常用的、强大的包

下载

changeColor()作用域链的低位指向的是它自己的作用域。在changeColor()中,有anotherColor和swapColor2个属性。

接下来开始执行changeColor()函数,在函数内部又创建了一个swapColor()函数,创建之后立刻执行这个函数。此时的作用域链内存模型如下图所示:

502.jpg

同样,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闭包-匿名函数和函数的作用域链的内容,更多相关内容请关注PHP中文网(www.php.cn)!

相关文章

java速学教程(入门到精通)
java速学教程(入门到精通)

java怎么学习?java怎么入门?java在哪学?java怎么学才快?不用担心,这里为大家提供了java速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
go语言 注释编码
go语言 注释编码

本专题整合了go语言注释、注释规范等等内容,阅读专题下面的文章了解更多详细内容。

32

2026.01.31

go语言 math包
go语言 math包

本专题整合了go语言math包相关内容,阅读专题下面的文章了解更多详细内容。

23

2026.01.31

go语言输入函数
go语言输入函数

本专题整合了go语言输入相关教程内容,阅读专题下面的文章了解更多详细内容。

16

2026.01.31

golang 循环遍历
golang 循环遍历

本专题整合了golang循环遍历相关教程,阅读专题下面的文章了解更多详细内容。

5

2026.01.31

Golang人工智能合集
Golang人工智能合集

本专题整合了Golang人工智能相关内容,阅读专题下面的文章了解更多详细内容。

6

2026.01.31

2026赚钱平台入口大全
2026赚钱平台入口大全

2026年最新赚钱平台入口汇总,涵盖任务众包、内容创作、电商运营、技能变现等多类正规渠道,助你轻松开启副业增收之路。阅读专题下面的文章了解更多详细内容。

268

2026.01.31

高干文在线阅读网站大全
高干文在线阅读网站大全

汇集热门1v1高干文免费阅读资源,涵盖都市言情、京味大院、军旅高干等经典题材,情节紧凑、人物鲜明。阅读专题下面的文章了解更多详细内容。

195

2026.01.31

无需付费的漫画app大全
无需付费的漫画app大全

想找真正免费又无套路的漫画App?本合集精选多款永久免费、资源丰富、无广告干扰的优质漫画应用,涵盖国漫、日漫、韩漫及经典老番,满足各类阅读需求。阅读专题下面的文章了解更多详细内容。

170

2026.01.31

漫画免费在线观看地址大全
漫画免费在线观看地址大全

想找免费又资源丰富的漫画网站?本合集精选2025-2026年热门平台,涵盖国漫、日漫、韩漫等多类型作品,支持高清流畅阅读与离线缓存。阅读专题下面的文章了解更多详细内容。

85

2026.01.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
React 教程
React 教程

共58课时 | 4.4万人学习

TypeScript 教程
TypeScript 教程

共19课时 | 2.6万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 3.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号