- 当函数可以记住并访问所在的词法作用域时,就产生了闭包,即使函数是在当前词法作用域之外执行。
function foo() {
var a = 2;
function bar(){
console.log(a);
}
return bar;
}
var baz = foo();
baz(); // 2
- 无论通过何种手段将内部函数传递到所在的词法作用域意以外,他都会持有对原始定义作用域的引用,无论在何处执行这个函数,都会使用闭包。
- 无论何时何地,如果将函数当作第一级的值类型并到处传递,就会看到闭包在这些函数的应用。只要使用了回调函数,实际上就是在使用闭包。
for循环中的闭包
for (var i = 0; i < 5; i++) { (function (j) { setTimeout(function timer() { console.log(j); }, 1000 * j); })(i); }
模块
- 基础
function CoolModule() {
var something = 'cool';
var another = [1,2,4];
function doSomething() {
console.log( something );
}
function doAnother() {
console.log(another.join(' ! '));
}
return {
doSomething: doSomething,
doAnother: doAnother
}
}
var foo = CoolModule();
foo.doSomething();
foo.doAnother();
- 单例模式
var foo = (function CoolModule() {
var something = 'cool';
var another = [1,2,4];
function doSomething() {
console.log( something );
}
function doAnother() {
console.log(another.join(' ! '));
}
return {
doSomething: doSomething,
doAnother: doAnother
}
})();
foo.doSomething();
foo.doAnother();
- 修改公共API
var foo = (function CoolModule(id) {
function change() {
publicAPI.identify = identify2;
}
function identify1() {
console.log( id );
}
function identify2() {
console.log(id.toUpperCase);
}
var publicAPI = {
change: change,
identify: identify1
}
return publicAPI;
})('foo module');
foo.identify(); //foo module
foo.change();
foo.identify(); // FOO MODULE
- 现代模块机制
var MyModules = (function Manager(){
var modules = {};
// name:模块明 deps:依赖模块 impl:模块实现的功能
function define(name, deps, impl) {
for(var i = 0; i < deps.length; i++){
deps[i] = modules[deps[i]];
}
modules[name] = impl.apply(impl, deps);
}
function get(name) {
return modules[name];
}
})();
MyModules.define("bar", [], function(){
function hello(who) {
return "Let me introduce: " + who;
}
return {
hello: hello
}
})
MyModules.define("foo", ['bar'], function() {
var hungry = "Hippo";
function awesome() {
console.log(bar.hello(hungry).toUpperCase());
}
return {
awesome: awesome
}
});
var bar = Mymodules.get("bar");
var foo = Mymodules.get("foo");
// let me introduce: hippo
console.log( bar.hello("hippo") );
// LET ME INTRODUCE: HIPPO
foo.awesome();
- 未来模块机制:import、export、module
小结
- 当函数可以记住并访问所在的词法作用域,即使函数上在当前词法作用域之外执行,这时就产生了闭包。
- 模块有2个主要特征:(1)为创建内部作用域而调用了一个包装函数;(2)包装函数的返回值必须至少包含一个对内部函数的引用,这样就会创建涵盖整个包装函数内部作用域的闭包。