首页 > 代码库 > 我眼中的JavaScript闭包

我眼中的JavaScript闭包

一、变量的作用域

  要理解闭包,首先必须理解Javascript特殊的变量作用域。

  变量的作用域无非就是两种:全局变量和局部变量。

  JavaScript语言在函数内部可以访问外部的变量,但是在函数外部不可以使用函数内部的变量,也就是局部变量。

  在函数内部可以访问外部的变量。

  比如这样:

var num=20;
function func1(){   
  console.log(num);
}
func1(); //得到的值为20

  另一方面,在函数外部自然无法读取函数内的局部变量。

  比如这样:

function func1(){
    var num=20;
}
console.log(num); // num is not defined(报错)

 

二、如何在函数外部去得到局部变量的值

  有时候,我们想要去得到函数内部的变量,应该怎么办呢?我们可以在函数的内部,再定义一个函数,从而来达到我们的目的。

function func1(){
    var num = 20;
    function func2(){
        return num
    }
    return func2;
}
var result = func1();    
console.log(result()); //得到的值为20

  在上面的代码中,函数func2被包括在函数func1内部,这时func2可以调用func1中的所有局部变量。但是反过来就不行,func1不能调用func2内部的局部变量。这就是Javascript语言特有的作用域链。子级会一级一级地向上寻找所有父级的变量,最终找到全局变量为止。

  在这个段代码中,函数func2就是闭包。

 

三、闭包的概念

  官方的解释是:闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。相信很少有人能直接看懂这句话,因为他描述的太学术。

  我们可以简单地理解为,闭包就是能够读取其他函数内部变量的函数,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。

 

四、闭包的用途  

  闭包最大的用处有两个:

  ① 可以读取函数内部的变量

  ② 变量持久化,让变量的值始终保持在内存中

  如何来理解变量持久化呢?请看下面这段代码:

function fn1(){
    var num = 18;
    function fn2(){
        return ++num;
    }
    return fn2;
}
var result = fn1();
console.log(result());  //得到的值为19
console.log(result());  //得到的值为20  
console.log(result());  //得到的值为21     

  在这段代码中,result实际上就是闭包fn2函数。它一共运行了三次,第一次的值是19,第二次的值是20,第三次的值是21。这证明了,函数fn1中的局部变量num一直保存在内存中,并没有在fn1调用后被自动清除。

  为什么会这样呢?原因就在于fn1是fn2的父函数,而fn2被赋给了一个全局变量,这导致fn2始终在内存中,而fn2的存在依赖于fn1,因此fn1也始终在内存中,不会在调用结束后,被垃圾回收机制(garbage collection)回收。

 

五、闭包的优缺点

  优点:

    ① 逻辑连续,当闭包作为另一个函数调用的参数时,避免你脱离当前逻辑而单独编写额外逻辑。

    ② 方便调用上下文的局部变量。

  缺点:

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

 

  闭包和作用域有着密不可分的关系,真的是“想说爱你不容易”!

  全文完!

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

<style>p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 19.0px Consolas; color: #888471 }</style> <style>p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 19.0px Consolas; color: #888471 }</style> <style>p.p1 { margin: 0.0px 0.0px 0.0px 0.0px; font: 19.0px Consolas; color: #888471 }</style>

我眼中的JavaScript闭包