Javascript最重要的特性之一是使用闭包。由于使用闭包,当前作用域总是可以访问外部作用域。因为Javascript没有块级别,只有函数域,闭包的使用与函数密切相关。

模拟私有变量

复制代码代码如下所示:

函数计数器(开始){

var =开始;

返回{

增量:函数(){

计数+;

},

获取:函数(){

返回计数;

}

}

}

var =计数器(4);

foo.increment();

foo.get(5); / /



这里计数器返回两个闭包:函数增量和获取。这两个函数总是保持对计数器作用域的访问,因此它们总是可以访问计数器范围中定义的变量计数。

私有变量的工作机制

因为Javascript不能在引用和赋值的范围内,所以在这种情况下,无法直接访问外部计数中的内部私有变量。

复制代码代码如下所示:

新计数器(4);

foo.hack =函数(){

计数= 1337;

};



上述代码不会改变计数器范围内的计数变量的值,因为在计数器中没有定义哈克。

循环闭合

最容易犯的错误之一是在循环中使用闭包。

复制代码代码如下所示:

对于(var i = 0;i < 10;i + +){

setTimeout(){()函数(

console.log(我);

},1000);

}



上面的代码不输出0到9,但输出是10倍10。

上述不愿透露姓名的不断引用变量i的console.log当函数被调用时开始输出,这是循环的结束和变我已经10。

为了避免上述错误,我们需要为每个周期创建变量i值的副本。

避免引用错误

为了在循环中复制变量的值,最好的方法是在外层添加一个匿名即时执行函数。

复制代码代码如下所示:

对于(var i = 0;i < 10;i + +){

(函数(e){)

setTimeout(){()函数(

console.log(E);

},1000);

})(一);

}



外部匿名函数接收循环变量i作为第一个参数,并将其值复制到自己的参数E。

外部匿名函数传递参数E的setTimeout,所以setTimeout有参考参数E和E这个参数的值不会改变,因为外部循环。

另一种方式来达到同样的效果是返回一个匿名函数在匿名函数在setTimeout。

复制代码代码如下所示:

对于(var i = 0;i < 10;i + +){

setTimeout((function(e){)

返回函数(){

console.log(E);

}

}(一),1000)

}



此外,还可以实现绑定方法。

复制代码代码如下所示:

对于(var i = 0;i < 10;i + +){

setTimeout(console.log.bind(控制台,我),1000);

}



在文章的结尾,我们得出结论:

(1)闭包是一种设计原则,它通过分析上下文来简化用户的调用,并允许用户在不知情的情况下实现自己的目的。

(2)对闭包的在线主流分析实际上与闭包原理相反。如果我们需要了解闭包的细节,我们将无法设计闭包。

(3)尽量少学。