阅读 986

“四说闭包” 惊艳面试官|8月更文挑战

这是我参与8月更文挑战的第4天,活动详情查看:8月更文挑战

目录

  1. 先说闭包是什么?
  2. 在说函数的创建和执行看闭包(引述:堆栈、EC、AO、VO、scope)
  3. 然后说闭包的作用以及在项目中的引用场景,以及带来的问题
  4. 最后说闭包引发的高级编程技巧,在框架源码中的使用,或者自己写类库的怎么使用

前言

不管是初级、中级的前端面试中,还是高级的前端面试中,闭包这个问题都会被拿来考验面试者。不同能力的面试者对这个问题的回答也是差别比较大的,

常见的面试问答,有如下几种场景。

青铜面试者

闭包是xx...。它的危害xx...。

闭包1.jpeg

钻石面试者

闭包是xx...。它的特点是xx...,它的危害xx...。我们日常怎么使用xx...。

闭包2.png 这两类的面试者是非常常见的,不能说回答的不好,但是回答的也不能算惊艳,那如何回答好闭包的问题了,今天小编就“四说闭包”,哪四说了,请往下看。

1. 先说闭包是什么?

  • 官方说法:闭包就是指有权访问另一个函数作用域中的变量的函数。
  • MDN 说法:闭包是一种特殊的对象。它由两部分构成:函数,以及创建该函数的环境。环境由闭包创建时在作用域中的任何局部变量组成。
  • 自我理解:把函数执行,形成私有上下文,并且保存和保护私有变量的机制,称之为“闭包” ,它是一种机制。

自我理解可以起到画龙点睛的作用,说明你不仅学了,用了,还自己理解了。

2. 在说函数的创建和执行看闭包(引述:堆栈、EC、AO、VO、scope)

一般很多面试者不会从底层来看闭包,如果你能从函数执行来说闭包,那你就超越了其他面试者。在面试官心里的地位上升了一截。如何说,接着往下。

浏览器在加载页面会把代码放在栈内存( ECStack )中执行,函数进栈执行会产生一个私有上下文( EC ),此上下文能保护里面的使用变量( AO )不受外界干扰,并且如果当前执行上下文中的某些内容,被上下文以外的内容占用,当前上下文不会出栈释放,这样可以保存里面的变量和变量值,所以我认为闭包是一种保存和保护内部私有变量的机制。

函数执行

  1. 形成私有上下文,函数每一次执行 都是从新形成一个全新的私有上下文,和之前执行产生的上下文没有必然的联系。
  2. 进栈执行
  3. 创建 AO
  4. 初始化作用域链[[ scopechain ]]:< EC < FN >, 作用域< ECXXX >>或者也可以这样理解< AO, VO(G) >
  5. 初始化 this
  6. 初始化arguments
  7. 形参赋值
  8. 变量提升
  9. 代码执行
  10. 遇到变量就先看是否是自己私有的,不是自己私有的按照作用域链上查找,如果不是上级的就继续线上查找,,直到 EC(G),变量的查找其实就是一个作用域链的拼接过程,拼接查询的链式就是作用域链。

image.png

正常情况下,代码执行完成之后,会有三类情况。

  • 当前上下文的某些东西被上下文以外的某些东西占用,那么当前上下文就不会被释放,就形成了闭包。
  • 如果没有被占用就是执行完成之后就被释放,不会形成闭包。
  • 除了这上面两种情况还有一种情况是,上下文没有被占用,但是要紧接着被用一次,这样没有用完之前是不能释放的,用完在释放,这样就形成了一个临时不被释放闭包。

3. 然后说闭包的作用以及在项目中的引用场景,以及带来的问题

函数执行会形成全新的私有上下文,这个上下文可能被释放,也可能不被释放,不论是否被释放,它的作用是:

  • 保护:划分一个独立的代码执行区域,在这个区域中有自己私有变量存储的空间,而用到的私有变量和其它区域中的变量不会有任何的冲突(防止全局变量污染)
  • 保存:如果上下文不被销毁,那么存储的私有变量的值也不会被销毁,可以被其下级上下文中调取使用

在实际的项目中,会基于闭包把自己编写的模块内容包裹起来,这样编写就可以保护自己的代码是私有的,防止和全局变量或者是其他的代码冲突,这一点是利用保护机制。

在没有使用 ES6 的 let 之前,我们循环处理事件绑定,在事件触发需要用到引所值的时候,我们基于闭包,把每一轮循环的引所值保存起来,这样来实现我们的需求。只不过现在基于 let 会产生块级作用域来保护需要保存的内容(机制类似于闭包)。

但是不建议过多的使用闭包,因为使用不被释放的上下文,是占用栈内存空间的,过多的使用会导致渲染页面变慢,所以要合理的使用闭包。

4. 最后说闭包引发的高级编程技巧,在框架源码中的使用,或者自己写类库的怎么使用的

除了在这些传统的业务开发中会引用闭包,可以讲讲自己之前在研究别人的源码和自己写一些插件的时候,往往会利用一些JS高阶编程技巧俩是吸纳代码的管理和功能的开发,他们的机制都是使用闭包,例如:惰性函数、柯里化函数、compose函数。

总结

从理论、底层运行机制、实践等角度来回答闭包,不仅能看出你基础能力的深度,也能看出你基础能力的广度。好了,这就是本篇文章的全部内容,希望可以帮你更好的理解闭包,也希望对你面试有所帮忙。

如果觉得写得还行,帮忙点个赞吧。

文章分类
前端
文章标签