Modularity(模块化-无模块化)

 
第一阶段:无模块化
 
简单的将所有的js文件统统放在一起。但是这些文件的顺序还不能出错,比如jquery需要先引入,才能引入jquery插件,才能在其他的文件中使用jquery。
 
优点:
  • 相比于使用一个js文件,这种多个js文件实现最简单的模块化的思想是进步的。
 
缺点:
  • 模块直接在全局工作,大量模块成员污染全局作用域;
  • 没有私有空间,所有模块内的成员都可以在模块外部被访问或者修改;
  • 一旦模块增多,容易产生命名冲突;
  • 无法管理模块与模块之间的依赖关系;
  • 在维护的过程中也很难分辨每个成员所属的模块。
函数封装
 
优点
  • 有一定的功能隔离和封装
 
缺点
  • 污染了全局变量
  • 模块之间的关系模糊
命名空间方式(对象封装)
 
每个模块只暴露一个全局对象
命名空间的方式只是解决了命名冲突的问题
 
优点
  • 一定程度上优化了命名冲突,降低了全局变量污染的风险
  • 有一定的模块封装和隔离,并且还可以进一步语义化一些
 
缺点
  • 并没有实质上改变命名冲突的问题
  • 外部可以随意修改内部成员变量,还是容易产生意外风险
IIFE(立即执行函数)
 
使用立即执行函数表达式(IIFE,Immediately-Invoked Function Expression)为模块提供私有空间
 
  • 将每个模块成员都放在一个立即执行函数所形成的私有作用域中,
  • 对于需要暴露给外部的成员,通过挂到全局对象上的方式实现.
  • 带来了私有成员的概念,私有成员只能在模块成员内通过闭包的形式访问,
  • 解决了前面所提到的全局作用域污染和命名冲突的问题
 
优点:
  • 实现了基本的封装
  • 只暴露对外的方法操作,有了 public 和 private 的概念
 
缺点:
  • 模块依赖关系模糊
 
// 函数封装

└─ stage-1
    ├── module-a.js
    ├── module-b.js
    └── index.html

// module-a.js 
function foo () {
   console.log('moduleA#foo') 
}

// module-b.js 
var data = ‘something'


<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <title>Stage 1</title>
</head>
<body>
  <script src="module-a.js"></script>
  <script src="module-b.js"></script>
  <script>
    // 直接使用全局成员
    foo() // 可能存在命名冲突
    console.log(data)
    data = 'other' // 数据可能会被修改
  </script>
</body>
</html>

 

// 命名空间方式(对象封装)

  // module-a.js
  window.moduleA = {
    method1: function () {
      console.log('moduleA#method1')
    }
  }

  // module-b.js
  window.moduleB = {
    data: 'something',
    method1: function () {
      console.log('moduleB#method1')
    }
  }

  <!DOCTYPE html>
  <html>
  <head>   
    <meta charset="UTF-8">   
    <title>Stage 2</title>
  </head>
  <body>   
    <script src="module-a.js"></script>  
     <script src="module-b.js"></script>   
    <script>
      moduleA.method1();
      moduleB.method1(); // 模块成员依然可以被修改
      moduleA.data = 'foo'
    </script>
  </body>
  </html>

 

// IIFE

  // module-a.js
  ;(function () {
    var name = 'module-a'
    function method1() {
      console.log(name + '#method1')
    }
    window.moduleA = {
      method1: method1
    }
  })()

 

// IIFE  引入依赖

  // module.js文件
  (function (window, $) {
    let data = 'www.baidu.com';
    //操作数据的函数
    function foo() {
      //用于暴露有函数
      console.log(`foo() ${data}`);
      $('body').css('background', 'red');
    }
    function bar() {
      //用于暴露有函数
      console.log(`bar() ${data}`);
      otherFun(); //内部调用
    }
    function otherFun() {
      //内部私有的函数
      console.log('otherFun()');
    }
    //暴露行为
    window.myModule = { foo, bar };
  })(window, jQuery);


// index.html文件
<!-- 引入的js必须有一定顺序 -->
<script type="text/javascript" src="jquery-1.10.1.js"></script>
<script type="text/javascript" src="module.js"></script>
<script type="text/javascript">
    myModule.foo();
</script>

 

// 揭示模块模式 Revealing module pattern

  var myGradesCalculate = (function () {
    // 在函数的作用域中下面的变量是私有的
    var myGrades = [93, 95, 88, 0, 55, 91];
    var average = function () {
      var total = myGrades.reduce(function (accumulator, item) {
        return accumulator + item;
      }, 0);
      return 'Your average grade is ' + total / myGrades.length + '.';
    };
    var failing = function () {
      var failingGrades = myGrades.filter(function (item) {
        return item < 70;
      });
      return 'You failed ' + failingGrades.length + ' times.';
    };
    // 将公有指针指向私有方法
    return {
      average: average,
      failing: failing,
    };
  })();
  myGradesCalculate.failing(); // 'You failed 2 times.'
  myGradesCalculate.average(); // 'Your average grade is 70.33333333333333.'

 

 
 
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值