第一篇 说说闭包

来源:互联网 发布:淘宝品牌选择 编辑:程序博客网 时间:2024/06/07 03:22

去年就嚷嚷写博客了,结果学前端那么久,都没有把自己心得体会在CSDN里写下来,全记在印象笔记里了。现在重温笔记,就慢慢把它转移到这吧,不过自己的经验太少太菜,所以还是停留在很基础的部分,目的想要把遇到的坑都记录下来。

强大的闭包

第一篇就说说JS里面强大的闭包吧。在我刚学前端的时候,自不量力去面试前端实习生的时候,被面试官问到一个问题,就是——“你知道什么是闭包吗?”
我思考了下,“不就是函数么”“那,你写一个闭包给我看看”
我当时还真就写了一个function
当时真是特别傻,不过JavaScript权威指南里确实是在函数这章里介绍的闭包,通俗的说,所有JavaScript里的function都是一个闭包,不过并不能体现我们说的强大的闭包

作用域

我们都知道JavaScript是弱类型语言,所以相对其他面向对象的语言,它真是很好理解对象这个概念,就是万物皆对象,所有函数也是对象。Javascript语言还有一个特殊之处,就在于函数内部可以直接读取全局变量。我们也知道,局部变量在函数执行结束时会自动消解,函数外部无法读取。

var n=100;function f1(){alert(n);}f1(); // 100
function f2(){ var n=100; alert(n);}f2();//error   注意如果函数内声明的变量不带var的话,其实表示的是n为全局变量

所以可以推论,如果一个函数嵌套一个子函数,父函数的局部变量对于子函数是可见的,而子函数的局部变量对于父函数是不可见的,子函数属于在父函数的作用域内。这就是JavaScript常说的“作用域链”。子对象会一级一级地向上寻找所有父对象的变量。所以,父对象的所有变量,对子对象都是可见的,反之则不成立。
所以,如果把子对象作为返回值,那岂不可以在函数外部访问到内部变量了吗。于是,我们常见的闭包是这样的:

function f1(){    var n=100;    function f2(){        alert(n);    }    return f2;}var result=f1();result();// 100

因为f1()对象返回的是内部函数f2,所以在这段代码中内部函数f2被赋给了全局对象result,所以f2始终存在于内存中,而f2依赖于f1,所以f1也不会被当垃圾回收掉,f2所引用的内部变量一直存在于内存中不会被回收。
这就是我们常说的闭包:当内部函数 在定义它的作用域 的外部 被引用时,就创建了该内部函数的闭包 ,如果内部函数引用了位于外部函数的变量,当外部函数调用完毕后,这些变量在内存不会被 释放,因为闭包需要它们。

闭包的作用

既然那么奇妙,所以通常在这些场景的时候可以想到用它
- 保护函数内变量安全。//外部函数的变量只有内部函数才能引用,没有别的途径可以引用哦。
- 在内存中维持一个变量。//还定义全局变量就low了。
- 通过保护变量安全来实现JS私有属性和私有方法。
原来觉得闭包好绕好难懂,所以尽量避免用它,但后面慢慢学习写jquery插件的时候,发现真的——学前端怎么可以不懂闭包

避免闭包滥用内存

既然闭包可以由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。例如

function f1(){    var n=100;    return function f2(){    return n;    }    n=null;//释放内存} 

好吧,没有深入继续讲闭包….下次吧。

0 0
原创粉丝点击