javascript之函数作用域和闭包[function scope and closure]

what is the closure?

在计算机领域当中, a closure is a function that is evaluated in an environment containing one or more bound variables. 当该函数被调用时, 它可以访问该环境中的变量,直接使用closure的例子如,函数式语言如ML和LISP。

在其它一些语言中构造对象也通常使用closure。

在一些语言当中, 一个closure在一个函数中定义另外函数时出现,同时inner function引用了outer的local variable。在运行的时候, 当outer function执行时, 一个closure就会形成, 它包含inner function的代码以及对该closure需要的、outer function的变量的引用。

closure可以被用来为function关联一组私有变量,这些变量会在一组函数调用后一直有效,也就是变量的状态会保持。而这些变量的作用域仅为定义这些变量的函数的范围,所以它们不会被其它外部的程序访问。定义的一个变量的值会在多次访问的过程中一直存储。作为结果,可以使用closure来实现状态隐藏,因此可以实现面向对象编程的封装。

javascript中的函数作用域和闭包:

例子一

var x = "global";

function f() {

     var x = "local";

     function g() {

         alert(x);

    }

     g();

}

f();

如例子一,当f();执行前时,当前的scope chain可以想象为 global obj,而var x = “global”为global的属性,当f被调用是,一个新的call object被创建,不妨称其为callee_f, 所以当前的scope chain 为global obj<--callee_f,而var x=“local”成为callee_f的属性。在f函数的执行过程当中, g被调用,则此时g的call object被创建, 称之为callee_g, 此时的scope chain为globa obj<--callee_f<--callee_g,  所以在g执行的时候, alert(x)中的x为called_f的x, global的x被屏蔽掉了, 显示为local。 当g执行完成以后,唯一指向g的引用为callee_g会被从scope chain中移除,所以在没有指向g的已用,故g将会在合适的时机被垃圾回收。其它雷同。

例子二

uniqueID = (function() {

    var id = 0;

    return function(){return id++;};

})();

global<--callee_outer<--callee_inner, 同时global-->callee_inner有一个global或其它obj对callee_inner的reference。尽管 callee_outer在outer function调用结束是不再对callee_inner进行引用, 而callee_inner仍然保存了对callee_outer的引用,所以此时可以看做 global-->callee_inner-->callee_outer, outer function的属性和状态被保存了下来, 但外部访问不了这些属性或者状态, 仅能通过inner function的引用通过定义好的函数接口来访问该outer function 的内部状态。

posted @ 2011-07-18 18:46  yub0yue  阅读(253)  评论(0编辑  收藏  举报