闭包

2020-06-15  本文已影响0人  d68caad2b350

1 闭包的含义

1.1MDN上对闭包的解释

函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起构成闭包closure)。也就是说,闭包可以让你从内部函数访问外部函数作用域。在 JavaScript 中,每当函数被创建,就会在函数生成时生成闭包。

1.2我对闭包的理解

每个函数都是一个闭包,函数F()在其私有空间定义的变量在函数空间外是不可见的,由于F()是可以在全局空间中被调用的,所以在函数中新定义并返回一个新的Inner()函数,用来返回F()的的私有变量,从而生成一个可以访问F()私有空间的新的全局函数。

下面是一个简单的闭包的例子:

function F(param) {

    var N = function() {

        return param;

    }

    param++;

    return N;

}

>var inner = F(123)

>inner();

124

inner()返回的是递增更新之后的值,由此可以看出,函数所绑定的是作用域本身,而不是一个值。

2 常见的闭包错误

2.1 错误代码

function F() {

    var arr = [], i;

    for (i = 0; i < 3; i++) {

        arr[i] = function () {

            return i;

        };

    }

    return arr;

}

> var arr = F();

>arr[0] () ;  >arr[1] () ; >arr[2] () ;

3 3 3

这并不是我们想要的结果,因为我们在这里创建了三个闭包,它们都指向了一个共同的局部变量i,但是闭包并不会记录它们的值,它们所拥有的只是相关域在创建时的一个连接(即引用)。

2.2 正确代码:

方法一:即时函数

function F() {

    var arr = [], i;

    for( i = 0; i < 3; i++) {

        arr[i] = (function (x) {

            return function () {

                return x;

            }

        }(i));

    }

    return arr;

}

在这里,不再创建一个返回i的函数了,而是将i 传递给了另一个即时函数,在该函数中,i被赋值给了局部变量x,这样一来,每次迭代中的x就会拥有各种不同的值了。

方法二:普通内部函数

function F() {

    function binder(x) {

        return function() {

            return x;

        };

    }

    var arr = [], i ;

    for (i = 0; i < 3; i++) {

        arr[i] = binder(i);

    }

    return arr;

}

该方法是在每次迭代过程中,在中间函数内将i的值本地化。

3 闭包的应用

3.1 getter与setter

假设现在有一个变量,表示某个特定区间内的值,我们不想把它暴露给外部,所以将它保护在相关函数的内部,然后引入两个额外的函数——一个用于获取变量值,另一个用于给变量重新赋值。

3.2 迭代器

function setup(x) {

    var i = 0;

    return function() {

        return x[i++];

    };

}

> var next = setup(['a','b','c']);

>next();

3.3回调

function changeSize(size){

    return function(){ document.body.style.fontSize = size + 'px'; };

}

var size12 = changeSize(12);

var size14 = changeSize(20);

document.getElementById('size-12').onclick = size12;

document.getElementById('size-20').onclick = size14;

作为一个回调(事件触发时调用的函数)绑定到事件。

参考:JavaScript面向对象编程指南(第二版)

上一篇 下一篇

猜你喜欢

热点阅读