js闭包,从js作用域理解js闭包

js什么是闭包?

《你不知道的JavaScript 上卷 》---> 当函数可以记住并访问所在的词法作用域时就产生了闭包,即使函数是在当前词法作用域以外的地方执行

《JavaScript权威指南》  ---> 函数体内部的变量都可以保存在函数作用域内,这种特性在计算机科学文献中称为‘’闭包‘注4(注4:这个术语非常古老,是指函数变量可以被隐藏于作用域链之内,因此看起来是函数将变量“包裹”了起来)。

《JavaScript高级程序设计 第三版》  ---> 闭包是有权访问另一个函数作用域中变量的函数

上面的三本书中都简短的描述了闭包。闭包是这么简单吗?先不管简不简单我们往下看。上面都提到一个作用域的东西。所以弄清楚闭包得先弄清楚js作用域所以先开始搞懂什么是作用域?不深究作用域是干什么的有什么功能。这里简单的将作用域理解为 代码能被访问的范围。要理解的更深一点看一下我另一篇翻译的文章https://www.cnblogs.com/ruoyin/p/9034294.html

例如 :

<script type="text/javascript">

function QAQ() { var a = 666; //a在函数QAQ()的作用域内 }

</script>
这里a被访问的范围也就是 QAQ()这个函数 ,在这个函数外面是访问不到a这个变量的。这里可以说a在函数QAQ()的作用域内。那么如果我们在函数QAQ()外面写一个var b=999
<script type="text/javascript">

var b = 999; //这里b在window的作用域内,即全局作用域内

function QAQ() {
var a = 666; //a在函数QAQ()的作用域内 }
</script>

因为在Web浏览器中,全局执行环境被认为是window对象即全局对象。b被访问的范围为全局,当然可以在QAQ里面访问到b 。QAQ被访问的范围也为全局 。a被访问的范围为 QAQ这个函数里面。所以b 和函数QAQ都在全局作用域内。a在QAQ的作用域内。

现在我们来看个例子:

<script type="text/javascript">

function QAQ() {//QAQ的作用域  全局
    var a = 666;    //a的作用域 QAQ   和xx函数的作用域一样
    function xx() { //xx的作用域 QAQ  和a的作用域一样
        console.log(a);//因为这个a所在的作用域是xx函数里面。xx函数和上面的a是在同一个作用域 所以能访问到a
    }
    return xx;/*这里将没有运行的函数xx作为返回值返回出去*/
}

var yy = QAQ();/*运行QAQ后拿到xx函数然后付给yy*/

yy();/*等于执行xx函数*/

</script>

运行结果:控制台打印了   666

分析:a的作用域是QAQ这个函数,按js的运行机制  来说当函数QAQ运行结束  a会被销毁。在QAQ外面是找不到a的值的,但是却被return出来的xx函数运行后给打印出来。说明了什么? 说明我们在a的作用域范围以外的地方访问到了a。由于js的垃圾回收机制知道存在对a的引用,a没有被垃圾机制回收销毁。这就是闭包。(这里就不深入研究怎么引用怎么,被垃圾回收机制回收的了,因为我不会啊!等我真正理解了我在补上)

总结: 现在回想在以前写的代码里面寻找变量或函数。在他作用域以外的地方被访问或执行了的例子,体会闭包。闭包就是对一种现象的描述。看完这篇文章应该要明白闭包这个现象。

               -----记录原生js的学习。以上也许有理解错误的地方,或者不合适的地方。还请指正相互学习。不明白的地方也可以留言。解决问题就是最好的学习方式!

猜你喜欢

转载自www.cnblogs.com/ruoyin/p/9034276.html