什么是闭包

对闭包的看法,为什么要用闭包?说一下闭包原理以及应用场景

闭包是JavaScript特有的一种函数嵌套结构,打破了作用域链的规则,是能够读取其他函数内部变量的函数,
本质:定义在函数内部的函数(函数嵌套函数),将函数内部和函数外部连接起来的一个桥梁。
原理:形成闭包结构时,内存函数引用外层函数的局部变量,新形成的作用域叫做闭包(closure)作用域。闭包会一直在栈中被挂起,生成一个不被销毁的函数空间变量常驻内存 直到手动销毁。
销毁闭包:当一个对象没有被引用时会被垃圾回收机制回收,而销毁闭包的方式就是赋值为null
形成闭包的三个条件

  1. 函数嵌套函数(至少两个函数)
  2. 在内层的函数中使用外层函数的局部变量或参数
  3. 内层函数作为返回值返回

用途

  1. 希望一个变量常驻在内存中(延长变量作用域、生命周期),使已经运行结束的函数中的变量对象继续保留在内存中,因为闭包函数保留这个变量的引用,所以这个变量对象不会被不会被垃圾回收机制回收 GC
  2. 使我们在函数外部能够访问到函数内部的变量。通过在外部调用闭包函数,从而在外部能够访问到函数内部的变量
  3. 避免全局变量污染

缺点

  1. 概念复杂不易理解
  2. 占用过多系统资源(内存),大量滥用闭包可能造成 栈溢出 IE->(内存泄漏)
  3. 功能被模块化开发取代(模块化是以闭包为基础构建的)

关于闭包会造成内存泄漏?知乎一位网页的看法:
image.pngjs闭包测试
使用场景

  1. 通过循环在页面上多个dom节点绑定事件
  2. 封装私有变量(计时器) 自执行的匿名函数保存循环变量
  3. 延续局部变量的寿命
  4. 高阶组件
  5. 函数防抖 用于记录一个计时器

沙箱模式

一种设计模式:解决特定问题给出的简洁而优化的解决方案
解决:变量私有化以后的访问和操作
利用闭包 把所有函数或者属性 变量都放在一个函数内部

面试题

函数默认行为:

  1. 定义函数

在堆里开辟一个空间,将函数体内的代码存入
把空间地址赋值给栈里面的变量(函数名)

  1. 调用函数

按照存储的地址找到函数存储空间
在调用栈 开辟一个 函数执行空间 在函数执行空间里进行形参赋值和预解析(先形参赋值再预解析)
把函数存储空间里的代码复制一份给函数执行空间执行
代码执行完毕,这个新开辟的函数执行空间销毁

  1. function closure(i = 0) {
  2. return function (n) {
  3. console.log(n + i++)
  4. }
  5. }
  6. var foo = closure();
  7. var bar = closure(1)
  8. foo(1)
  9. closure(2)(3)
  10. bar(4)
  11. closure(4)(5)
  12. bar(5)
  13. foo(6)
  14. console.log(i)

image.png
image.png