什么是闭包呢?
闭包就是定义在父函数里面的一个子函数,这个子函数可以访问父函数的变量和作用域。然后把这个子函数返回出去暴露在全局作用域下就形成了一个闭包。
它是如何产生的呢?
闭包也就是一个函数,它是基于词法作用域自然产生的,也就是每当你创建了一个函数,这个函数他就构成了一个闭包,只是平常开发中只有嵌套函数里的闭包经常发挥作用。
什么是词法作用域呢?
词法作用域就是定义在词法阶段的作用域,也是就是变量和块作用域在哪词法作用域就在哪
什么是词法阶段?
JS语音在引擎上执行之前会有三个步骤,分别是分词(也就是词法分析,也就是所说的词法阶段)然后是解析,最后是代码生成。
词法阶段呢就是由一串字符组成一个字符串后,然后再分解成一个一个的代码块,这个代码块也称为词法单元。比如var a = 2;那么这个var就是一个代码块a = 2 ; 都是一个代码块,这个由组成再分解成代码块的阶段就叫做词法阶段。
解析就是由一组字符串转换为一组成元素逐级嵌套的语法树,也叫做抽象语法树。
代码生成就是这个将这个抽象语法树转换为可执行代码的这个过程叫做代码生成,简单来说就是将这个抽象语法树转换为机器可执行的指令
JS中有哪些块级作用域?
let,const,
没有块级作用域有哪些问题?
内层变量提升会覆盖外层变量,
还有用来循环的变量他不会消失而是直接泄露成为全局变量导致循环出错。
块级作用域有哪些好处?
允许块级作用域任意嵌套,
外层作用域无法读取内层作用域的变量,
内层作用域可以定义外层作用域的同名变量
闭包的概念
外部函数调用之后其变量对象本应该销毁,但因为有闭包的存在我们仍可以访问外部函数的变量对象
闭包的特性
函数嵌套函数
函数内部可以引用外部的参数和变量
参数和变量不会被垃圾回收机制回收。
闭包的好处和坏处
好处有可以减少全局变量,减少参数传递数量
坏处有常驻内存,增大内存消耗,使用不当易造成内存泄漏
什么是内存泄漏,为什么会造成内存泄漏?
首先每个浏览器都会有自己的一套回收机制,当分配出去的内存不适用时就会回收。
内存泄漏的根本原因就是你的代码中分配了一个回收不掉的内存,浏览器无法回收。如果这些回收不掉的内存还在一直不停的分配的话就会导致内存不足,所以会造成内存泄漏。
闭包本身不会造成内存泄漏,但闭包过多会造成内存泄漏。因为闭包就是能否访问外部变量的一个函数,而函数又是必须要保存再内部的对象所以位于函数执行上下文中的所有变量也都需要保存在内存中,这样就不会被回收,如果一旦循环引用或创建闭包,就会增大内存,从而导致内存泄漏
解决方法可以在内部变量不使用时,把外部的引用置为null
闭包的生命周期
产生:在嵌套的内部函数定义执行完成时就产生了
死亡:在嵌套的内部函数成为垃圾对象时
立即执行函数是什么函数
它就是一个普通函数,它只是声明完立即执行,它也不是闭包,它只是实现了闭包中的变量私有化的功能