JS基础核心之闭包

JavaScript012

JS基础核心之闭包,第1张

在A函数中嵌套B函数,B函数访问A函数中的变量。将A函数复制给C函数并执行。

那么在大多数的理解中,包括许多著名的书籍,文章里都以函数C的名字代指这里生成的闭包。而在chrome中,则以执行上下文A的函数名代指闭包。

而我的理解是:闭包更准确的说是一项技术或者一个特性:只要运用具备阻止垃圾回收机制回收和突破作用域链限制的技术,就是闭包。像是《JavaScript权威指南》打的比方,像是把变量包裹了起来,形象的称为“闭包”。

如果非要指明哪个函数是闭包的话,我愿意将A函数称为定义闭包的函数,C函数为执行闭包的函数。

a. 在函数内部创建新的函数;

b. 新的函数在执行时,访问了函数的变量对象。

c. 闭包是在函数被调用执行的时候才被确认创建的。

一句话总结:==函数中闭包判定的准则,即执行时是否在内部定义的函数中访问了上层作用域的变量。==

闭包,阻止垃圾回收机制。

闭包,突破作用域链接。

《你不知道的JS中》的示例:

模块模式需要具备两个必要条件:

1.必须有外部的封闭函数,该函数必须至少被调用一次(每次调用都会创建一个新的模块实例)。

2.封闭函数必须返回至少一个内部函数,这样内部函数才能在私有作用域中形成闭包,并且可以访问或者修改私有的状态。

什么时候使用模块模式?

如果必须创建一个对象并一某些数据对其进行初始化,同时还要公开一些能够访问这些私有数据的方法,那么就可以使用模块模式。

哪些地方有用到模块模式?

最典型的就是JQuery库,jQuery和$标识符就是JQuery模块的公共API,但它们本身都是函数(由于函数也是对象,它们本身也可以拥有属性)

以后单独拿一个章节,来具体讲讲现在的模块化和未来的模块化机制。

具体的内容在函数的柯里化的章节中详细分析。

戳此传送门

输出6的原因是:被封闭在一个共享的全局作用域中,实际上只有一个i。

依次输出1-5的原因是:在迭代内部使用IIFE(立即表达函数)为每个迭代生成一个新的作用域,将外部变量的值传递进去并被引用(阻止垃圾回收机制回收),使得每个回调函数都能访问到正确值的变量。

戳此传送门

什么是闭包(Closure)?

网上流传各种说法,在Javascript语言中,我的理解是: 保存着其他函数内部变量的函数,就是闭包。

挺绕的,但不虚,让我们一步步揭开它的神秘面纱!

要理解闭包,我们得先搞清楚以下几个概念:

JS的作用域分两种:全局作用域、局部作用域(也可称为函数作用域)

总的来说,Js作用域的一般机制就是:内部可访问外部的变量,外部无法访问内部的变量。

那么这套作用域机制是如何实现的呢?答案是:通过作用域链

在Js中,每当一个函数被执行,都会产生三个对象:

我们通过实例配图讲解,例如有如下 js 文件:

当浏览器运行解析 example.js 后,首先创建了全局执行环境 (Window 对象)、Window 作用域链和 Global 全局活动对象,如图:

搞明白了作用域链,离弄清楚什么是闭包就仅一步之遥了! 我们来看看下面这个实例:

当执行 var func = outer() 时,情况如图:

接下来,当执行 console.log(func()) 时, 情况如图: