美文网首页
JavaScript闭包

JavaScript闭包

作者: agamgn | 来源:发表于2020-01-01 07:46 被阅读0次

前言

在面试过程中,闭包是常考的问题,在很多框架和库中也使用到了闭包,包括我们在平时写代码也或多或少使用到了闭包。

一、什么是闭包

闭包的概念描述很多,我比较认同《你不知道的JavaScript》这样描述:

当函数可以记住并访问所在的词法作用域时,就产生了闭包,即使函数是在当前词法作用域之外执行。

在正式理解闭包之前,我们需要清楚什么是作用域词法作用域内存回收机制

1.1、作用域

一言以蔽之,作用域就是一套规则,用于确定在何处以及如何查找变量(标识符)的规则,形象描述的话,可以认为它是一个封闭的空间,只允许在这个封闭的空间内进行一些操作,也将这个封闭空间称为私有作用域。
更多的参考本篇作用域以及作用域链

1.2、内存回收机制

内存回收机制就是不在用到的内存,我们系统就自动进行回收从而清理出空间供其他程序使用
更多的参考本篇JavaScript内存管理

二、讲解闭包

上面已经提到了闭包的概念,这里直接看一段代码:


闭包demo.png

这里可以很清晰的展示闭包:

  • fn2的词法作用域能访问到fn中的作用域
  • fn2当作一个值返回
  • fn执行之后,将fn2的引用赋值给f
  • 执行f,将输入变量count
    在第一次执行f()的时候,根据作用域链的规则(底层作用域没有声明的变量,会向上一级找,找到就返回,没找到就一直找,直到window的变量,没有就返回undefined)是没有疑问的输出1,那第二次的过程是怎样的呢? 继续执行那个函数的返回的方法,还是count+=1;然后再输出count ,这里问题就来了,不应该继续向上寻找,找到count=0;然后输出1吗?
    原因是因为f保存的是fn的执行结果,即fn2,所以count的值只声明了一次,那么第二次的count的值又是从哪里来的?
    这是第一次执行f()后留下来的那个变量。为什么函数变量执行完后没有被释放?这就是垃圾回收机制(标记清除)处理的一个问题了。
    由于再次执行f()的时候,再次引用了第一次fn()产生的变量count ,所以count没有被释放,第一次f(),count 的值为1,第二次执行f(),count的值再加1,自然就是2了。
    所以说如果执行两次fn,那么输出就应该都是1。
    闭包demo.png

三、再看一个例子

闭包demo3.png

我们的预期结果是1~10,但是确输出10次11。这是因为setTimeout中的匿名函数执行的时候,for循环都已经结束了,for循环结束的条件是i大于10,所以当然是输出10次11。
究其原因:i是声明在全局作用中的,定时器中的匿名函数也是执行在全局作用域中,那当然是每次都输出11了。
使用闭包解决:我们可以让i在每次迭代的时候,都产生一个私有的作用域,在这个私有的作用域中保存当前i的值。


闭包demo4.png

这样就达到我们的预期了。

四、闭包的应用

4.1、实现私有成员
闭包demo5.png
4.2、保护命名空间,避免污染全局变量
闭包demo6.png
上面这个用法,叫做函数柯里化,就是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术
闭包demo7.png
注意事项: 由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题

五、总结

理解闭包是迈向高级JS程序员的必经之路,理解了其解释和运行机制才能写出更为安全和优雅的代码。
代码地址

相关文章

  • JavaScript----闭包

    javascript之闭包 闭包的概念     闭包(closure)是 JavaScript 的一种语法特性。 ...

  • 学习JavaScript闭包和作用域笔记

    JS JavaScript闭包和作用域 闭包 JavaScript高级程序设计中对闭包的定义:闭包是指有权访问另外...

  • javascript中闭包是什么

    javascript中闭包是什么 JavaScript 变量可以是局部变量或全局变量。私有变量可以用到闭包。闭包就...

  • Javascript 闭包

    闭包 (注:所以案例以 javascript 实现) 初识闭包 什么是闭包 MDNClosures are fun...

  • 作用域闭包

    概览 背景知识:JavaScript内存管理、JavaScript作用域。 内容 1 闭包定义 闭包:当函数可以记...

  • JavaScript 作用域

    概览 背景知识:JavaScript内存管理、JavaScript作用域。 内容 1 闭包定义 闭包:当函数可以记...

  • 20170815 前端开发日报

    JavaScript闭包,只学这篇就够了 闭包不是魔法 这篇文章使用一些简单的代码例子来解释JavaScript闭...

  • JavaScript深入理解-闭包(Closure)

    推荐文章:学习Javascript闭包(Closure)- 阮一峰javascript深入理解-从作用域链理解闭包...

  • 闭包

    学习Javascript闭包(Closure)

  • JS之闭包与IIFE

    本篇文章主要讨论了: JavaScript引擎 全局对象 闭包 循环 + 闭包 IIFE + 闭包 1.JavaS...

网友评论

      本文标题:JavaScript闭包

      本文链接:https://www.haomeiwen.com/subject/pwzmoctx.html