对于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。
理解重点:作用域链创建时机 局部变量绑定对象 词法作用域规则 底层运行机制
分享到:
相关推荐
总之,深入理解JavaScript闭包对于编写高效、可维护的代码至关重要。掌握闭包不仅有助于解决实际问题,还能提高编程技巧和对JavaScript语言机制的理解。在日常开发中,无论是用于实现模块化、数据封装,还是处理异步...
深入理解JavaScript系列(16):闭包(Closures) 深入理解JavaScript系列(17):面向对象编程之一般理论 深入理解JavaScript系列(18):面向对象编程之ECMAScript实现 深入理解JavaScript系列(19):求值策略...
深入理解javascript原型和闭包(01)——一切都是对象 深入理解javascript原型和闭包(02)——函数和对象的关系
总的来说,深入理解原型和闭包对于掌握JavaScript至关重要,因为它们不仅体现了JavaScript独特的设计思想,还是区别于其他主流编程语言的关键特性。无论是原型链和作用域链的理解,还是函数作为一等对象的灵活使用,...
JavaScript闭包是编程语言中一个重要的概念,尤其对于JavaScript开发者来说,理解闭包至关重要。闭包的本质是一个函数,这个函数能够访问并操作其外部作用域的变量,即使在其外部作用域已经不再存在的情况下也能保持...
JavaScript 闭包是一种重要的编程概念,它涉及到函数和作用域之间的关系。闭包是指一个函数能够访问并操作其外部作用域中的变量,即使这个函数在外部作用域...理解和熟练掌握闭包对于JavaScript开发者来说至关重要。
深入理解JavaScript的闭包技术整理.pdf
深入理解JavaScript系列(16):闭包(Closures) 深入理解JavaScript系列(17):面向对象编程之一般理论 深入理解JavaScript系列(18):面向对象编程之ECMAScript实现 深入理解JavaScript系列(19):求值策略...
Javascript中有几个非常重要的语言特性——对象、原型继承、闭包。其中闭包 对于那些使用传统静态...本文将以例子入手来介绍Javascript闭包的语言特性,并结合一点 ECMAScript语言规范来使读者可以更深入的理解闭包。
本文将以例子入手来介绍Javascript闭包的语言特性,并结合一点 ECMAscript语言规范来使读者可以更深入的理解闭包。闭包是Closure, 资源太大,传百度网盘了,链接在附件中,有需要的同学自取。
在JavaScript中,闭包是一种特殊的函数,它能够访问并操作其定义时的作用域,即使该作用域在其执行时已经不存在。闭包的概念是基于JavaScript的词法作用...理解并掌握闭包对于编写高效、安全的JavaScript代码至关重要。
JavaScript中的闭包是一种强大的...理解并熟练运用闭包是JavaScript开发中的重要技能,它能够帮助开发者编写更加灵活和高效的应用代码。在实际开发中,应根据需求选择合适的闭包实现方式,并注意避免不必要的内存占用。
深入理解闭包,还需要了解JavaScript的作用域、作用域链、执行上下文等概念。作用域决定了变量的可见性,全局作用域在整个脚本中都可访问,而函数作用域仅在函数内部可见。当函数执行时,会创建一个执行上下文,其中...
JavaScript 闭包是一种强大的特性,它允许函数访问和操作其外部作用域的变量,即使在其外部函数执行完毕后,闭包依然能...通过深入理解闭包,开发者可以更好地利用 JavaScript 的特性,写出更高效、更易于维护的代码。
JavaScript是一种动态类型的...通过这些深入的讲解,你应该能更好地理解JavaScript中对象、原型、函数和闭包的工作原理,为你的JavaScript开发打下坚实的基础。在实际编程中,灵活运用这些知识可以解决许多复杂的问题。