深入理解javascript闭包

对于javascript闭包的理解纠结了一段时间,总是没有理解透彻,现参考资料终于理解清楚,原来闭包是这样简单。
首先,我们知道函数对象可以通过作用域链关联起来,函数体内的变量可以保存在函数作用域链内,该种特性在计算机学中称为“闭包”。
要理解闭包我们需要理解javascript的作用域链和词法作用域规则。
javascript每一段代码都有一个与之对应的作用域链,该作用域链是一个对象或者链表。javascript需要查找变量x的值时,会从作用域链第一个对象开始查找。在javascript的顶层代码(不包含函数定义的代码)作用域链由一个全局变量组成;对于无嵌套函数的函数定义,作用域链有两个对象,一个是函数局部对象,另一个是全局对象;在一个嵌套函数定义下,作用域链至少有3个对象。当定义一个函数时,实际是保存一个作用域链,当调用函数时会创建一个新的对象保存函数变量并将函数对象添加到这个作用域链上,同时创建一个更长的新的作用域链用以表示函数调用的作用域链,即每次函数调用的作用域链都不相同。
javascript采用词法作用域,即函数执行依赖于函数变量作用域,这个作用域是在函数定义时决定而不是函数调用时决定。
首先我们看下例子:
var scope = "this is a globle scope.";//定义全局对象
function chkscope(){
var scope = "this is a local scope."//定义局部变量
function f(){
return scope;
}
f();
}
chkscope();
当执行最后一行代码后返回"this is a local scope."大家应该都会很清楚其原因:局部变量优先级高于全局变量。但是我们将代码调整一下
var scope = "this is a globle scope.";//定义全局对象
function chkscope(){
var scope = "this is a local scope."//定义局部变量
function f(){
return scope;
}
f;
}
chkscope()();
将函数体内f后的一对圆括号调整到代码最后,代码执行到最后一行也是返回"this is a local scope.",嵌套在函数体内的作用域链的变量始终是局部变量,即无论f何时调用返回的始终是local。
这就是之前困扰我的地方。大多数可能会和我一个这样理解,在外部函数调用返回后外部函数创建的局部变量会立即消失,代码执行到最后一行应该返回undenifined。其实从作用域链和javascript词法作用域以及程序底层运行来看不难理解。从前面我们知道函数运行用到作用域链,而函数作用域链由函数定义决定。如果函数局部变量存放栈中,外部函数调用返回时函数局部变量肯定会立即消失,但是从作用域链的定义知道,函数定义时是将变量存放在对象中并且添加到对应作用域链上,如果没有引用指向对象,对象会被当做垃圾回收掉。回到闭包定义,函数对象通过作用域链互相关联起来,即每一个定义的嵌套函数都对应各自的作用域链,这些作用域链都指向该绑定变量。如果没有外部引用指向这些作用域链,那么外部函数调用返回时,他们也会和这个变量绑定对象一起删除,但是嵌套函数将该对象值作为返回值或者存放在某个属性中,此时就有一个外部引用指向嵌套函数对应的作用域链,嵌套函数和局部变量绑定对象都不会被删除,因此嵌套在函数体内的作用域链的变量始终是局部变量,即,无论f何时调用返回的始终是local。
理解重点:作用域链创建时机 局部变量绑定对象 词法作用域规则 底层运行机制
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值