1. 什么是闭包
you don't know js定义为: 我们不在某个函数的lexical scope中执行它,也就是说,我们不在定义这个函数的环境中执行它,这个时候就产生了闭包。
所以,闭包出现在js的很多地方,当我们把函数作为值传递的时候,大多数情况下就是在使用闭包。
第一颗栗子🌰
var bar=(function (person){
return function(){
console.log('greetings, '+person);
}
})('jack');
bar(); //'greetings, jack'
你看,我们在global环境下执行了bar(),而不是在定义bar的foo函数里面执行,这就是一个闭包。
2. 闭包和scope
其实,我们每执行一次函数,都会产生了对应的scope;一般来说,函数执行结束之后,它对应的scope中定义的变量都会在内存中被清理掉,但是闭包创建了一个特例。 我们创建闭包往往经历2个必要步骤:
- 我们执行(invoke)父函数,这个父函数中定义了子函数;
- 我们在任何环境下都可以invoke子函数,子函数不管在哪里执行,都可以访问父函数scope中定义的变量。
hhh,父函数的内心是喜悦的,我的scope还在内存中!我没被释放掉噢!
3. 理解闭包可以帮助我们理解模块化
wrapper function返回对象作为接口,把想要暴露的函数放在对象中,通过public function就可以访问wrapper function的private data和private function.
第二颗栗子🌰:
var myModule=(function(){
function change(){
publicObj.identity=foo;
}
function foo(){
console.log('foo');
}
function bar(){
console.log('bar');
}
var publicObj={
idenity: bar,
change: change
}
return publicObj;
})();
myModule.identity(); //'bar'
myModule.change();
myModule.identity(); //'foo'
这个模式稍稍经过一点改变,我们就可以理解CommonJS了
//lib1.js
function person(name){
this.showName=function(){
console.log('name: '+name);
}
this.greeting=function(){
console.log('hello!');
}
}
module.exports=person;
//main.js
var module=require('./lib1.js');
var instance1=new module('amy');
instance1.showName();
instance1.greeting();