浅谈javaScript中的闭包

来源:互联网 发布:linux ifconfig 找不到 编辑:程序博客网 时间:2024/05/18 01:36

在讲述javaScript中的闭包时,先做一点准备工作。那就是javaScript中作用域的概念。
作用域与作用域链:

//js中的作用域链,var personName = "张三";function getPersonName(){    alert(personName);}//打印出了张三,personName的作用域是全局的,方法内部可以访问到getPersonName();

上面这段代码中,在方法内部被访问到。我们在方法内部添加personName变量,再次看效果。

var personName = "张三";function getPersonName(){    var personName = "李四";    alert(personName);}//打印出了李四,因为方法内部定义了personName,getPersonName();

打印结果是李四,personName是方法中的局部变量,要是我们在方法中再定义一个personAge的变量。在全局直接使用是不行的。在js中,查找变量的模式是,先在当前作用域查找,如果没有找到此变量,就会往更大的作用域查找。如果还没有,就再往上查找。这就是所谓的作用域链。

垃圾回收机制:
js中存在两种垃圾回收的方式,一种是标记法,另一种是引用计数法。标记法就是对进入作用域的变量标记为使用,然后离开作用域就标记为不再使用。引用计数的方式就是只要对象被持有一次,计数 就增加一次。当这个对象引用计数为0,则即为要回收的对象。垃圾回收并不是时时的,是带有周期性的。因为垃圾回收是很消耗性能的。在java中,垃圾回收执行一次,所有的线程都会终止。等待执行结束后再执行,要是时时进行垃圾回收的话,程序也会出现内存抖动等情况,影响用户体验。但这个时时也并不是就按照一定时间间隔去执行,当系统内部内存不足时,也会进行垃圾回收来释放内存。总之,还是比较智能的。

闭包:
其实闭包就是利用了以上说的这两点,那具体是怎么用的呢?我会一步一步的带大家了解。

var add = (function count(){    var salary = 1000;    return function addSalary(){        salary += 1000;        return salary;    }})();console.log("------salary-------------",add()); //2000console.log("------salary-------------",add()); //3000console.log("------salary-------------",add()); //4000

这是闭包比较经典的例子,我们来分析一下。首先(count)()用了两个小括号,这代表什么意思呢? 第一个,是给定函数一个作用域,意思就是说,这个函数是一块单独的作用域了,第二个()表示执行一下这个count函数,这个函数的返回值是addSalary()这个函数。注意,在addSalary()函数中引用了count()函数的salary 变量,为什么能引用salary变量在作用域的介绍中我们已经说的很明白了,当前add创建出来之后,是一个全局的变量,如果页面没有被销毁,那这个salary能被内存释放吗?答案肯定是不能的。所以说,在多次执行add()之后,salary会累加。
这就是闭包的原理。

闭包的优缺点:
知道原理之后,优缺点就很明显了,优点就是可以保存变量值,方便程序调用。缺点就是比较浪费内存。

原创粉丝点击