闭包表面现象:
综上所以什么是闭包:现在这个father()就是一个 闭包,由父函数和子函数构成,子函数在调用的时候读取父函数的变量,使函数是在当前词法作用域之外执行就产生了闭包。
(1)有父子函数的关系
(2)子函数调用了父函数的变量
(3)子函数有调用
闭包底层原理
必须懂的几个点
1.变量的生命周期:局部变量的生命周期在函数执行完成之后就到头了;全局变量的生命周期在页面关闭之后就到头了。
2.垃圾回收机制:定期检查你数据使用情况
策略:标记清除和引用计数。
注意:如果说这个数据有引用的关系,就不会被回收。
3.执行上下文(当前代码的执行环境,EC)
创建EC后会执行两个阶段1.创建阶段2.代码执行阶段
(1)全局环境
(2)函数环境
(3)eval环境
4.执行上下文栈(ECS),函数调用栈(call stack)
(1)变量对象
普通函数,定义函数的时候是嵌套的,调用的时候也是嵌套的,
闭包函数,定义函数的时候是嵌套的,调用的时候是独立的。
闭包由什么构成?
闭包由两部分构成:函数,以及创建该函数的环境。(环境由闭包创建时在作用域中的任何局部变量组成。)
闭包的本质?
闭包其实是JavaScript函数作用域的副作用产品。
闭包是一种特殊的对象。
通常情况下,函数的作用域及其所有变量都会在函数执行结束后被销毁。但是,如果创建了一个闭包的话,这个函数的作用域就会一直保存到闭包不存在为止。
闭包的应用
私有方法只能被一个类中的其他方法所调用,但是JavaScript没有提供这种原生支持,所以我们可以通过闭包来模拟私有方法。
私有方法自然有私有方法的好处,私有方法有利于限制对代码的访问,而且可以避免非核心的方法干扰代码的公共接口,减少全局污染。
使用闭包的注意事项
内存泄漏
因为闭包可以使函数中的变量都保存在内存中,造成很大的内存消耗,所以如果 不是某些特定的任务需要使用闭包,我们不要滥用它。
使用不当的闭包会在IE(IE9)之前造成内存泄漏问题。因为它的JavaScript引擎使用的垃圾回收算法是引用计数法,对于循环引用将会导致GC(下文会介绍)无法回收垃圾。
垃圾回收机制
垃圾回收也就是GC(Garbage Collection)。
GC把程序不用的内存空间视为垃圾,找到它们并且将它们回收,让程序员可以再次利用这部分空间。
不是所有的语言都有GC,一般存在于高级语言中,如Java、JavaScript、Python。那么在没有GC的世界里,程序员就比较辛苦,只能手动去管理内存,比如在C语言中我们可以通过malloc/free,在C++中的new/delete来进行管理。