闭包

什么是闭包?

闭包是指那些能够访问自由变量的函数

自由变量是指作用域外的变量

当内部函数使用外部函数的变量就形成了一个闭包。

闭包的优缺点?

  • 优点:使我们能够在函数内部访问到函数外部的变量,可以通过这种方法来创建私有化变量,在私有化的基础上保持变量,常常应用在节流防抖等应用场景中。

  • 缺点:也就在闭包另一个用途中,已经运行结束的函数执行上下文中的变量对象继续留在内存中,因为闭包函数保留了这个变量对象的引用,所以变量对象 不会被垃圾回收机制回收,因为不会被回收,就可能导致内存泄漏的情况。

    扩展知识点: 垃圾回收机制内存泄漏

作用域、作用域链的理解

作用域

作用域是指代码中定义变量的区域,作用域分为全局作用域函数(局部)作用域块级作用域

  • 全局作用域是指在代码中任何位置都可以访问的作用域,是整个程序的最外层作用域,在浏览器环境中,全局作用域通常指window对象。
    全局作用域有弊端,过多的全局作用域变量会污染全局命名空间,容易引起命名冲突。
    如果直接给定义的变量赋值,变量就会成为全局变量。

  • 函数作用域就是指每个函数都会创建自己的作用域,变量的作用域仅限于函数内部,函数外部无法访问函数内部定义的变量。
    函数作用域的机制保证变量不会与其他代码中的变量产生冲突,并且可以避免变量污染全局命名空间。

  • 块级作用域指一对花括号{}中的代码块,通过 ES6 的letconst关键字,可以声明块级作用域的变量和常量,使其只在当前代码块中有效
    ,代码块外部无法访问。var声明的变量不具备块级作用域,所以推荐使用letconst来声明变量,避免由于变量作用域引起的问题。

作用域链

  1. 概念

作用域链就是在当前作用域找不到所需变量,那这个变量就是自由变量,然后就去父级作用域查找,依次向上查找,直到访问到 window 对象就终止,这
一层层关系就是作用域链。

  1. 作用

作用域链的作用是保证对有权访问的所有变量和函数的有序访问,通过作用域链,可以访问到外层环境的变量和函数。

执行上下文的理解

执行上下文分为全局执行上下文和函数执行上下文。

在执行 js 代码之前会先解析代码,解析的时候会先创建一个全局执行上下文栈,先把代码中要执行的变量、函数声明
都拿出来,变量先赋值为 undefined,函数先声明好可以使用。然后才开始正式地执行程序。
在一个函数执行之前,会创建一个函数执行上下文环境,跟全局执行上下文类似,不过会多出 arguments,this 和函数的参数。

执行上下文栈

js 引擎用执行上下文栈来管理执行上下文。

  • 当 js 执行代码时会先遇到全局代码,然后创建全局执行上下文并压入执行栈中,每当遇到一个函数调用,就会为该函数创建一个新的执行上下文并压入栈顶,引擎会执行位于栈顶的函数,当函数执行完后,执行上下文从栈中弹出,继续执行下一个上下文,当所有代码都执行完毕后,从栈中弹出全局执行上下文。