JavaScript 里的闭包是什么?应用场景有哪些?

关注者
1,350
被浏览
398,376

69 个回答

看一个例子:

var foo = ( function() {
    var secret = 'secret';
    // “闭包”内的函数可以访问 secret 变量,而 secret 变量对于外部却是隐藏的
    return {
        get_secret: function () {
            // 通过定义的接口来访问 secret
            return secret;
        },
        new_secret: function ( new_secret ) {
            // 通过定义的接口来修改 secret
            secret = new_secret;
        }
    };
} () );

foo.get_secret (); // 得到 'secret'
foo.secret; // Type error,访问不能
foo.new_secret ('a new secret'); // 通过函数接口,我们访问并修改了 secret 变量
foo.get_secret (); // 得到 'a new secret'

引用 Douglas Crockford [1] :

之所以可能通过这种方式在 JavaScript 种实现公有,私有,特权变量正是因为闭包闭包是指在 JavaScript 中,内部函数总是可以访问其所在的外部函数中声明的参数和变量,即使在其外部函数被返回(寿命终结)了之后

需要注意的一点时,内部函数访问的是被创建的内部变量本身,而不是它的拷贝。所以在闭包函数内加入 loop 时要格外注意。另外当然的是,闭包特性也可以用于创建私有函数或方法。

--------

关于为什么在 JavaScript 中闭包的应用都有关键词“return”,引用 JavaScript 秘密花园中的一段话:

闭包是 JavaScript 一个非常重要的特性,这意味着当前作用域总是能够访问外部作用域中的变量。 因为 函数 是 JavaScript 中唯一拥有自身作用域的结构,因此闭包的创建依赖于函数。

--------

[1]Private Members in JavaScript -

Private Members in JavaScript

[2]JavaScript - The Good Parts -

JavaScript (豆瓣)

[3]JavaScript 秘密花园 - 闭包和引用 -

JavaScript 秘密花园

闭包就是由函数创造的一个词法作用域,里面创建的变量被引用后,可以在这个词法环境之外自由使用。( secure.wikimedia.org/wi

闭包通常用来创建内部变量,使得这些变量不能被外部随意修改,同时又可以通过指定的函数接口来操作。