作用域闭包

2017-07-24  本文已影响0人  后发而先制

如果你了解了之前关于词法作用域的讨论,那么闭包的概念几乎是不言自明的。

死板的例子:

function foo() {

var a = 2;

function bar() {

console.log( a );

}

return bar;

}

var baz = foo();

baz(); // 2 —— 朋友,这就是闭包的效果。

分析代码

而闭包的“神奇”之处正是可以阻止这件事情的发生。事实上内部作用域依然存在,因此没有被回收。

这个函数在定义时的词法作用域以外的地方被调用。闭包使得函数可以继续访问定义时的词法作用域。

JQUERY 闭包例子

function setupBot(name, selector) {

$( selector ).click( function activator() {

    console.log( "Activating: " + name );

} );

}

setupBot( "Closure Bot 1", "#bot_1" );

setupBot( "Closure Bot 2", "#bot_2" );

在定时器、事件监听器、Ajax 请求、跨窗口通信、Web Workers 或者任何其他的异步(或者同步)任务中,只要使用了回调函数,实际上就是在使用闭包!

循环和闭包

for (var i=1; i<=5; i++) {

setTimeout( function timer() {

console.log( i );

}, i*1000 );

} 输出都是6

闭包

for (var i=1; i<=5; i++) {

(function(j) {

setTimeout( function timer() {

      console.log( j );

}, j*1000 );

})( i );

}

模块

模块模式需要具备两个必要条件

1. 必须有外部的封闭函数,该函数必须至少被调用一次(每次调用都会创建一个新的模块实例)。

2. 封闭函数必须返回至少一个内部函数,这样内部函数才能在私有作用域中形成闭包,并且可以访问或者修改私有的状态。

当函数可以记住并访问所在的词法作用域,即使函数是在当前词法作用域之外执行,这时就产生了闭包。

模块有两个主要特征:(1)为创建内部作用域而调用了一个包装函数;(2)包装函数的返回值必须至少包括一个对内部函数的引用,这样就会创建涵盖整个包装函数内部作用域的闭包。

上一篇 下一篇

猜你喜欢

热点阅读