js 闭包理解

我们先看一下维基百科对于闭包的解释 这里我们先只描述下闭包的概念 在PHP、JavaScript、Ruby、 Python、Go、Lua、objective c、swift 以及Java(Java8及以上)等语言中都能找到对闭包不同程度的支持。

可能看了这个官方的解释会让你感觉云里雾里,我刚开始看的时候也很蒙,(这里我要很感谢我的老大  每次不明白的地方都会和我讲述清楚和背后的基础原理)通过几番战斗让我对闭包有了一个新的认识。

下面我们通过js来描述下闭包的问题

我理解的闭包定义是:闭包就是当一个函数即使是在它的作用域之外被调用时,也可以记住并访问它的作用域。

我们先看一段代码

可以看出函数 bar() 对于 foo() 内的作用域拥有访问权,在这我们 return  bar 引用的函数对象本身。

在执行 foo() 之后,我们将它返回的值(我们的内部 bar() 函数)赋予一个称为 baz 的变量,然后我们实际地调用 baz(),这将理所当然地调用我们内部的函数 bar(),只不过是通过把他复制给一个全局变量对象的属性baz

bar() 被执行了,在这个例子中,它是在它被声明的作用域 外部 被执行的。

foo() 被执行之后,一般说来我们会期望 foo() 的整个内部作用域都将消失,因为我们知道 引擎 启用了 垃圾回收器 在内存不再被使用时来回收它们。因为很显然 foo() 的内容不再被使用了,所以看起来它们很自然地应该被认为是 消失了

但是闭包的不会让这发生。内部的作用域实际上 依然 在使用,因此将不会消失。谁在使用它啦? 函数bar()本身

有赖于它被声明的位置,bar() 拥有一个作用域闭包覆盖着 foo() 的内部作用域,闭包为了能使 bar() 在以后任意的时刻可以引用这个作用域而保持它的存在。

bar() 依然拥有对那个作用域的引用,而这个引用称为闭包。闭包 使这个函数可以继续访问它定义的作用域

通过下面这个例子来说明 对那个作用域的引用,而这个引用称为闭包的解释

内部函数(timer)将它传递给 setTimeout()。但是 timer 拥有覆盖 wait(..) 的作用域的闭包,实际上保持并使用着对变量 message 的引用。

在我们执行 wait() 一秒之后,要不是内部函数 timer 依然拥有覆盖着 wait() 内部作用域的闭包是不会打印出messgae的值

我们可以得到在直白一点的定义

有权限访问另一个函数作用域内变量的函数称为闭包。

在闭包中因为变量被引用着所以不会立刻被垃圾回收,因此可以用来封装私有变量。这即是闭包存在优点也是缺点,

闭包的好处:1.实现变量缓存
2.实现封装,防止变量跑到外层作用域中,发生命名冲突
3.匿名自执行函数,匿名自执行函数可以减小内存消耗

闭包的坏处:由于闭包会使得函数中的变量都被保存在内存中,都会放在作用域链上面会加长作用域链 查找就会变慢 会影响网站性能,使用不当很容易造成内存泄露

闭包是javascript语言的一大特点,主要是设计私有的方法和变量。jquery框架很能说明闭包的应用不想让外部修改这些属性可以设计一个闭包来只提供方法获取

以上描述是个人对闭包的一些理解   欢迎大家指出问题和讨论

下篇讲述this与对象原型

猜你喜欢

转载自blog.csdn.net/qq_24884955/article/details/82785546