你不知道的JS系列 ( 16 ) - 模块和闭包

模块是闭包应用中最强大的一个。
function CoolModule() {
  var something = 'cool';
  var another = [1, 2, 3];

  function doSomething() {
    console.log( something);
  }

  function doAnother() {
    console.log( another.join('!'));
  }
  return {
    doSomething: doSomething,
    doAnother: doAnother
  }
}
var foo = CoolModule();
foo.doSomething(); // cool
foo.doAnother(); // 1!2!3

这个模式在 JavaScript 中被成为模块。首先,CoolModule 只是一个函数,必需通过调用它来创建一个模块实例。如果不执行,内部作用域和闭包都无法创建。

 

其次,CoolModule 返回一个用对象字面量预发{key:value,...}来表示的对象。这个返回的对象中含有对内部函数的引用。保持内部数据变量是隐藏且私有的状态。可以将这个对象类型的返回值看作本质上是模块的公共 API

 

模块模式需要具备两个条件
1、必须有外部的封闭函数,该函数必须至少被调用一次(每次调用都会创建一个新的模块)
2、封闭函数必须返回至少一个内部函数,这样内部函数才能在私有作用域形成闭包,并且可以访问或者修改私有的状态。

 

当只需要一个实例是,可以改进成单例模式
var foo = (function CoolModule() {
  var something = 'cool';
  var another = [1, 2, 3];

  function doSomething() {
    console.log( something);
  }

  function doAnother() {
    console.log( another.join('!'));
  }
  return {
    doSomething: doSomething,
    doAnother: doAnother
  }
})();
foo.doSomething(); // cool
foo.doAnother(); // 1!2!3

 

模块也是普通的函数,可以接受参数

function CoolModule(id){
  function identify(){
    console.log(id);
  }
  return {
    identify: identify
  }
}
var foo1 = CoolModule('foo 1');
var foo2 = CoolModule('foo 2');

foo1.identify();
foo2.identify();

 

模块模式另一个简单但强大的变化用法是,命名将要作为公共 API 返回的对象
var foo = (function CoolModule(id){
  function change(){
    // 修改公共 api
    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
通过模块实例的内部保留对公共 api 对象对内部因哟肱,可以从内部对模块实例进行修改,包括添加,删除方法和属性,以及修改它们的值

 

posted @ 2020-02-27 06:45  wzndkj  阅读(205)  评论(0编辑  收藏  举报