zoukankan      html  css  js  c++  java
  • JavaScript闭包(closure)

    闭包其实就是利用了函数作用域和匿名函数的知识,当函数A执行结束时,一部分变量变量被B引用,被引用的变量不能释放,形成了所谓的闭包。这里有篇很好的文章,可以参考一下。

    下面看一个小例子:

    运行上面的函数后,首先alert显示”second:3″,然后显示”第一个函数执行结束”,3秒后显示“first:3”。

    仔细看一下,函数show执行结束的时候,变量n应该被释放了,内存里也就不存在了,怎么过了3秒还能显示出”first:3″呢?闭包恰恰就在此产生了,当函数show执行结束的时候,想要释放内存里的n,但发现变量n还在被一个匿名函数引用,要在3秒后调用,根据JavaScript闭包原理,内存里的n被保留了下来,于是在三秒以后仍然可以调用n。

    下面看几种写法的区别:

    仔细看一下上面这种写法不是闭包,只是普通的函数调用而已。

    这种写法就是闭包,虽然结果是一样的,但原理不一样。

    上面这种写法也是闭包,虽然结果都是一样的,但原理却不一样。这里面看到了函数也可以当作对象也传递,函数show执行后return show2,把函数show2赋值给newshow,然后3秒后,调用newshow对象,执行函数show2。

    仔细比较上面3种写法,如果能悟出一些道理就好,闭包有些时候的确难理解。

    稍复杂一点的例子:

    上面代码中,又一次用了函数作为对象传递,n是匿名函数里的局部变量,外部是访问不到的。show是一个全局变量,应该访问不了变量n,但在函数show执行前,首先把函数匿名函数内部show2赋值给show,当后面函数show运行的时候,会调用show2的代码,而show2是可以访问n的,故结果显示为1、2、3。

    另外一点值得注意的,也是很经典的一个例子。

    运行后,不论点击哪一个li,都是alert提示“4”。这就是一个需要注意的地方:闭包允许内层函数引用父函数中的变量,但是该变量是最终值。闭包引用的变量i,是循环结束后的值,其实这是一个很常见的问题,解决方法也有很多。

    比较常见的就是给li[i]添加属性值,比如li[i].n=i;还有就是用闭包方法解决,这个函数本身就是闭包,所谓用闭包来解决闭包的问题。代码如下:

  • 相关阅读:
    js 中的 EventLoop
    线程的并发工具类
    xpath获取某个节点下的全部字节点的文本
    2020中国 .NET开发者大会精彩回顾:葡萄城高性能表格技术解读
    .NET 控件集 ComponentOne V2020.0 Update3 发布,正式支持 .NET 5
    log4net配置
    TP5.1 爬虫
    pip下载慢
    TP5.1 二维码生成
    composer插件集合
  • 原文地址:https://www.cnblogs.com/wangxy/p/4935358.html
Copyright © 2011-2022 走看看