JavaScript的作用域和闭包
首发于:https://mingjiezhang.github.io/
闭包和作用域有着千丝万缕的联系。
js的作用域
具体的作用域我就不展开叙述了。其中很重要的两点就是:js的作用域链机制和函数词法作用域在定义的时候就确定的。对于前者,js中每个函数都有自己的执行环境,执行流进入一个函数时,函数的环境就会被推入一个环境栈,函数执行完之后就把控制权归还,这也是垃圾回收机制的原理,当代码在一个环境中执行会创建变量对象一个作用域链,标识符解析是沿着作用域链一级一级搜索的。对于后者,有些人认为函数词法作用域是执行时确定的,但这是错误的,本身词法作用域的定义就于此违背,我们可以通过下面这个例子来证明。
function b(){
var x=3;
a();
}
function a(){
console.log(x);
}
b();//x is not defined.
如果函数作用域是执行时候确定的,那么按理结果应该是打印3。但是我们看到是x未定义,这完美地证明了a()的作用域链中是不存在b()的局部作用域。因此,我们可以确定函数词法作用域在定义的时候就确定的。
作个小总结:函数作用域是在函数定义的时候就确定了的,但是只有函数作用域需要通过执行函数来激活函数局部作用域,如果未执行函数或者函数执行完毕,该函数的变量对象的作用域都是不能被使用的或者被回收的,这点对于理解闭包十分重要。
初探闭包
闭包的定义有很多,在《You dont'konw JavaScript》中闭包的定义:当函数可以记住并访问所在的词法作用域时,就产生了闭包,即使函数是在当前词法作用域之外执行。
我们来解读下这句话,闭包怎么产生,就是一个内部函数可以记住它所在的作用域的时候,这个函数就是个闭包了,而且,这个函数在这个作用域外执行的时候,也是可以记住该作用域的。
我们先通过一个demo来解析这个定义。
function out(){
var a=1;
function in(){
console.log(a);
}
return in;
}//定义out函数
var temp=out();//将out函数执行返回的in函数引用赋值给temp变量
temp();//结果输出1
假如没有闭包:按照js的垃圾回收机制,在out()函数执行完毕的时候,out的内部作用域应该被销毁,也就是这时候变量a本应该销毁,这时候函数temp()中无法获得a声明所在的作用域。
不过闭包却可以改变这一切,out函数在执行完毕后,out内部作用域仍然存在。这时候,temp()函数执行的时候,可以记住并访问out()内部的作用域,这时候temp()函数可以访问a。
这就是闭包的神奇之处,虽然外部函数执行完毕,但是内部函数如果有变量引用外部函数作用域中的变量,那么该外部函数的变量对象就不会被回收,可以继续被使用。
闭包的意义和危险
闭包的意义就是可以让一个外部函数中的内部函数在非当前作用域中被使用,同时这个内部函数可以操作外部函数的作用域中的变量。模块的实现与闭包有很联系。具体的例子这边不展开叙述。
当然闭包也很危险,因为外部函数执行完毕后,外部函数的作用域的变量对象一直被引用,长期未被回收会造成内存泄漏,因此我们需要手动去销毁这些被引用的变量。
欢迎指正交流。未经允许,请勿转载。
JavaScript的作用域和闭包的更多相关文章
- 我认知的javascript之作用域和闭包
说到javascript,就不得不说javascript的作用域和闭包:当然,还是那句老话,javascript在网上都说得很透彻了,我也就不过多的强调了: 作用域:javascript并没有像其他的 ...
- 剖析JavaScript函数作用域与闭包
在我们写代码写到一定阶段的时候,就会想深究一下js,javascript是一种弱类型的编程语言,而js中一个最为重要的概念就是执行环境,或者说作用域.作用域重要性体现在哪呢?首先,函数在执行时会创建作 ...
- 你不知道的JavaScript(作用域和闭包)
作用域和闭包 ・作用域 引擎:从头到尾负责整个JavaScript的编译及执行过程. 编译器:负责语法分析及代码生成等. 作用域:负责收集并维护由所有声明的标识符(变量)组成的一系列查询,并实施一套非 ...
- JavaScript 函数作用域和闭包
函数作用域和闭包 词法作用域 它们在定义它们的作用域里运行,而不是在执行的作用域运行,但是只有在运行时,作用域链中的属性才被 定义(调用对象),此时,可访问任何当前的绑定. 调用对象 ...
- JavaScript从作用域到闭包
目录 作用域 全局作用域和局部作用域 块作用域与函数作用域 作用域中的声明提前 作用域链 函数声明与赋值 声明式函数.赋值式函数与匿名函数 代码块 自执行函数 闭包 作用域(scope) 全局作用域 ...
- javascript的作用域和闭包(三)闭包与模块
一些很重要的说明:前面三篇博客详细的介绍了,引擎与编译器和作用域的关系,重点需要理解的是编译器中的分词与词法分析,JavaScript的特有的“赋值操作的左右侧”引用操作:编译阶段的词法作用域的工作原 ...
- JavaScript的作用域与闭包
JavaScript的作用域以函数为界,不同的函数拥有相对独立的作用域.函数内部可以声明和访问全局变量,也可以声明局部变量(使用var关键字,函数的参数也是局部变量),但函数外部无法访问内部的局部变量 ...
- JavaScript之作用域和闭包
一.作用域 作用域共有两种主要的工作模型:第一种是最为普遍的,被大多数编程语言所采用的词法作用域,另外一种叫作动态作用域: JavaScript所采用的作用域模式是词法作用域. 1.词法作用域 词法作 ...
- 前端知识体系:JavaScript基础-作用域和闭包-JavaScript的作用域和作用域链
JavaScript的作用域和作用域链 作用域: 变量的作用域无非两种:全局作用域和局部作用域 全局作用域: 最外层函数定义的变量拥有全局作用域.即对任何内部函数来说都是可以访问的. <scri ...
- Javascript的作用域和闭包(一)
一.作用域是什么? 几乎所有的编程语言最基本的功能之一,就是能够存储变量的值,并且能访问和修改这些值. 修改变量值的过程我们通常在程序执行时,称为改变一个对象的状态.有了状态,让程序变得有非常有趣. ...
随机推荐
- 如何在IIS7或IIS7.5中导入导出站点及应用程序池.
为实现负载平衡,我们可能会使用多个WEB服务器,也就会需要给多个IIS配置同样的站点和应用程序池.那么我们需要一个一个的重新建吗?当然不用,我们只需要一些简单的命令就可以在IIS7(Windows S ...
- mysql安装过程中出现错误ERROR 1820 (HY000): You must SET PASSWORD before executing this statement解决
mysql安装过程中出现错误ERROR 1820 (HY000): You must SET PASSWORD before executing this statement解决 最近新装好的my ...
- S5PV210之Sate210-F DIY硬件,移植uboot,kernel,android 活动现在已经进入实施阶段吗,欢迎广大网友参与 !
大家一起来diy 超低价四核的exynos4412或者Cortex A8S5pv210开源开发板 商业版Sate210已经完成了好久了.Sate4412 也已经出来.但是这两个接口非常全,主要是针对企 ...
- Python Django 开发 4 ORM
第三篇最后写了,光知道那些基础的查询在项目中是没有什么卵用的,重点是实体关系映射(ORM),今天学习了,来记录一下,关键词:ForeignKey(多对一).OneToOneField(一对一).Man ...
- Webkit CSS properties
Webkit CSS properties -webkit-animation -webkit-animation-delay -webkit-animation-direction -webkit- ...
- AssetBundle系列——共享资源打包/依赖资源打包
有人在之前的博客中问我有关共享资源打包的代码,其实这一块很简单,就两个函数: BuildPipeline.PushAssetDependencies():依赖资源压栈: BuildPipeline.P ...
- 关于Assembly.CreateInstance()与Activator.CreateInstance()方法
于Assembly.CreateInstance()与Activator.CreateInstance()方法 动 态创建类对象,大多是Activator.CreateInstance()和Activ ...
- 【转载】Linux下动态共享库加载时的搜索路径详解
转载自:http://www.eefocus.com/article/09-04/71617s.html 对动态库的实际应用还不太熟悉的读者可能曾经遇到过类似“error while loading ...
- linux根目录下文件夹概览
/ 根目录 /bin 存放必要的命令 /boot 存放内核以及启动所需的文件等 /dev 存放设备文件 /etc 存放系统的配置文件 /home 用户文件的主目录,用户数据存放在其主目录中 /lib ...
- 开放产品开发(OPD):Archi 汉化工具下载
本文更新版本已挪至 http://www.zhoujingen.cn/blog/3378.html ------------------------------ 在OPD中,我们使用了ArchiMa ...