JS基础核心之闭包

JavaScript011

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(立即表达函数)为每个迭代生成一个新的作用域,将外部变量的值传递进去并被引用(阻止垃圾回收机制回收),使得每个回调函数都能访问到正确值的变量。

戳此传送门

闭包的概念

    所谓的闭包就是利用作用域的嵌套,将原本的局部变量进化成私有变量,同时在作用域的外部能够拿到该变量的环境,就叫做闭包!

闭包的特点

    1.比较消耗性能

    2.避免了全局变量的污染

    3.可以在外部操作内部的变量,方便 但是不安全

    4.低版本浏览器会造成内存的泄露

    5.将原本要删除的变量保存起来,方便下一次使用

闭包的原理

    表现 :作用域的嵌套

    本质 :函数的定义区域: 函数的定义作用域

               函数的执行区域: 函数的执行作用域

    关系 :执行时,可以拿到定义作用域的所有变量

    像这种利用作用域嵌套,拿到内部变量的 环境,都可以看做成闭包。(利用作用域的嵌套,触发了计算机的垃圾回收机制,将原本要删除的变量临时保存到新的作用域中)

  应用场景: 1.循环内绑定的事件  2. 事件处理函数  3.计时器 

随着互联网的不断发展,程序员在学习JavaScript编程开发上也有了更多的了解,今天我们就简单分析一下关于JavaScript编程解析机制以及闭包的一些常见问题。

js解析机制:js代码解析之前会创建一个如下的词法环境对象(仓库):LexicalEnvironment{}在扫描js代码时会把:1、用声明的方式创建的函数的名字2、用var定义的变量的名字存到这个词法环境中3、同名的时候:函数声明会覆盖变量,下面的函数声明会覆盖上面的同名函数4、函数的值为:对函数的一个引用变量的值为undefined5、如果用函数表达式的方式创建一个函数:varfn=function(){}这样词法环境中存的是一个变量名fn,并赋值为undefined在调用函数的时候如果在函数上面调用就会出现和变量一样的情况报错undefined这也是以两种不同方式创建函数的区别闭包:定义:(有多种定义)1、(比较通俗的定义):函数嵌套函数,内部函数可以引用外部函数的参数和变量,这些参数和变量不会被垃圾回收机制所回收2、在计算机科学中,闭包是词法闭包的简称,是引用了自由变量的函数,这个被引用的自由变量将和这个函数一同存在,即使已经离开了创造它的环境也不例外(意思就是不会被销毁)。

3、闭包是由函数和其相关的引用环境组合而成的实体。

(潜台词就是这个函数将和引用环境同时存在,必须有引用)综合来说,不管怎么定义都是在围绕着两个本质:函数在引用变量,这个变量将不会被销毁。

闭包的一个作用就是:我们能够通过闭包的方法来在外部访问到一个内部函数的变量很多人在解释闭包的时候都会把子函数return出去以后在外部调用,其实无论在哪里调用,闭包都已经形成了,只要是函数嵌套函数,并且子函数引用了父函数的变量,(不论子函数有没有被调用,电脑培训http://www.kmbdqn.cn/认为这个用一种方法证明:在子函数内部打断点,在f12中观察闭包里的内容,已经出现了引用函数,这时候调用还没有被执行)这个时候闭包已经形成了。