javascript闭包

  在学习javascript闭包之前,需要先了解一下"作用域链"。

每一段javascript代码都有一个与之关联的作用域链(scope chain),这个作用域链是一个对象列表或者链表,这组对象定义了这段代码"作用域中"的变量。当javascript需要查找变量x的值的时候,它会从链中的第一个对象开始查找,如果这个对象有一个名为x的属性,则会直接使用这个属性的值,如果第一个对象不存在名为x的属性,javascript会继续查找链上的下一个对象。如果第二个对象依然没有名为x的属性,则会继续查找下一个对象,以此类推。如果作用域链上没有任何一个对象含有属性x,那么就认为这段代码的作用域链上不存在x,并最终抛出一个引用错误异常。

  当定义一个函数的时候,它实际上保存了一个作用域链,当调用这个函数的时候,它创建一个新的对象来存储它的局部变量,并将这个对象添加至保存的那个作用域链上,同时创建一个新的更长的表示函数调用作用域的"链"。

  函数对象可以通过作用域链关联起来,函数体内部的变量都可以保存在函数作用域内,这种特性就称为"闭包"。也可以这样理解闭包,函数变量可以被隐藏于作用域链之内,看起来是函数将变量"包裹"了起来。

  概念说了一堆,来个示例可能会比较清晰。

  var a = 1;

  function testFun(){

    var a = 10;

    function tempFun(){return a;}

    return tempFun();    

  }

  testFun();

  上述例子执行的结果是返回10。

   对于上述例子,我们来做一下改动。

  var a = 1;

  function testFun(){

    var a = 10;

    function tempFun(){return a;}

    return tempFun;

  }

  testFun()();

  对于这个例子,很多人会下意识的认为返回结果为1,理由就是函数tempFun是在全局环境下执行的,因此会返回1。然而结果是返回10。

  由于javascript函数的执行用到了作用域链,这个作用域链是函数定义的时候创建的。

  嵌套的函数tempFun定义在这个作用域链里,其中的变量a是局部变量,不管在什么时候执行函数tempFun,这种绑定在执行tempFun依然有效,因此结果返回10而不是1。

  这里我们可以看到闭包的强大之处:它们可以捕捉到局部变量(参数),并一直保存下来,看起来像这些变量绑定到了在其中定义它们的外部函数。

 

posted on 2013-09-23 23:08  ArthurPatten  阅读(1106)  评论(2编辑  收藏  举报

导航