本文转载自微信公众号《前端思维框架》,作者ViktorHub。转载本文请联系前端思维框架公众号。在JavaScript语言中,闭包是其核心基础之一。可以说是一个特性,但是很多从事前端工作的程序员并没有真正理解它!关闭有多重要?如果你是刚接触前端的朋友,我可以肯定的告诉你,前端面试一定要问闭包。面试官往往会根据对闭包的理解来判断面试官的基本水平。保守估计前端面试官10人中至少有5人死于闭包。通过本文的讲解,希望你能重新认识闭包!函数被调用时会发生什么?为了理解闭包,我们首先需要充分理解JavaScript是如何工作的!那么调用函数时会发生什么?当浏览器在解析JS代码时,会进行预解析操作,会有一个js解析器,会进行两步操作:1.预解析,找东西(var函数参数);2.逐行解释代码。当解析器解释函数调用时,它将整个函数压入堆栈并为该函数创建一个新的执行上下文。函数内部可以看做一个小区域,有自己的作用域和执行线程,也是逐行解释的。当函数显式返回(到达return语句)或隐式返回(默认情况下函数返回undefined)时,函数会从堆栈中弹出并且其执行上下文也会被销毁。闭包是什么鬼?我们先来看这段代码://"HiJane"我们发现子函数printHi可以访问其父函数greet的全局作用域和局部作用域。请注意,我们实际上可以访问函数执行期间可用的“新”数据,而不是声明。这就是词法作用域在JavaScript中的工作方式。但是如果我们返回一个函数而不是仅仅在外部函数的主体中调用它会发生什么?看,魔法发生了!函数返回的函数不仅仅是一个简单的函数定义,它是定义加上它可以访问和需要执行的变量,存储在它自带的词法作用域中。我们刚才描述的是闭包。从形式上讲,闭包是一个“即使在其词法范围之外调用也能记住其词法范围”的函数。functioncreator(num){returnfunction(){num=num*2console.log(num)}}constdouble=creator(5)double()//10double()//20constdouble2=creator(7)double2()//14double2()//28double()//40正如我们在上面的代码片段中看到的,每当我们调用double时,它??都会更新存储在其词法作用域中的同一个变量(来自其父函数的num),这在技术上是一个隐藏的[[作用域]]函数具有的属性。如果你想知道闭包到底有什么用,请继续看下面的例子。模块封装闭包允许我们保护或隐藏某些信息。[[scope]]是一个隐藏属性,所以我们不能像使用标准对象那样访问和更新它。同样需要注意的是,我们可以返回一组存储在对象上的函数,它们都是闭包。在下面的代码片段中,我们利用了所谓的IIFE(立即调用函数),它允许我们消除调用外部函数的中间步骤,就好像我们在赋值时直接调用它一样。constmyModule=(function(){constapiKey="123456789"return{displayKey(){console.log(apiKey)}}})()myModule.displayKey()//"123456789"如果我们导出这个模块,会提供给其他人使用,而我们给他准备的API是不允许他更改apiKey的,这使得它成为一个只读属性,调用者除了在源代码中重写之外是不可能更改的。缓存和记忆假设您要创建一个简单的ID生成器。为确保始终返回比前一个更大的数字,也可以使用闭包。我们将缓存当前变量中的最高ID值。constnewID=(function(){letcurrent=0returnfunction(){return++current}})()newID()//1newID()//2当我们算法的时间复杂度很高的时候,这种缓存方式就非常有用,我们可以把部分结果存入缓存中,当我们做更大数的计算时,可以以缓存中的数据为依据。这个过程称为记忆。一个典型的例子是处理递归问题,例如斐波那契数列。constfactorialMemo=(function(){constcache={}returnfunctionfactorial(n){if(n===1||n===0){return1}elseif(cache[n]){returncache[n]}else{cache[n]=n*factorial(n-1)returncache[n]}}})()factorialMemo(5)//120//cacheobjectlookslike{'2':2,'3':6,'4':24,'5':120}factorialMemo(6)//6*cached120好了,今天的内容就到这里了,你明白闭包是什么鬼了吗?当然,一定要掌握好,需要在不断的实践和总结中自我体会!《面向对象分析与设计》书中有一句话很喜欢总结闭包。他是这样说的:“闭包是偷懒的对象,对象是自然闭包。慢慢体悟,欢迎评论交流,周末愉快~
