当我们讨论闭包的时候,其实在讨论变量和内存

350 阅读1分钟

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(),而不是在定义barfoo函数里面执行,这就是一个闭包。

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();