JavaScript 模块化(2)

504 阅读1分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

上一节,简单说了下模块化,他的进化史和几种模块化的规范,比较重要的ES6模块化简洁、方便;以及 CommonJS 模块化。这一节主要是讲解模块化进化史,从全局function模式到IIFE模式,是怎么演变过来的。

1. 全局function模式

首先我们创建二个js文件

  • module1.js
let data = 'module'

function fun() {
  console.log(`module1.js fun() ${data}`)
}
function bar() {
  console.log(`module1.js bar() ${data}`)
}
  • module2.js
let data2 = 'other data'

function fun() {
  console.log(`module2.js fun() ${data2}`)
}

把两个js中的方法名称写的一样,都为 fun

  • 创建一个index.html 引入这两个js文件
<script type="text/javascript" src="module1.js"></script>
<script type="text/javascript" src="module2.js"></script>
<script type="text/javascript">
  let data = "new data"
  fun()
  bar()
</script>

全局函数模式: 将不同的功能封装成不同的全局函数
问题: Global被污染了, 这样很容易造成起命名冲突

2. 命名空间模式

同样我们创建二个js文件

  • module1.js
let module1 = {
  data: 'module1',
  fun() {
    console.log(`module1.js fun() ${data}`)
  },
  bar() {
    console.log(`module1.js bar() ${data}`)
  }
}
  • module2.js
let module2 = {
  data: 'module2',
  fun() {
    console.log(`module2.js fun() ${data}`)
  },
  bar() {
    console.log(`module2.js bar() ${data}`)
  }
}
  • 创建一个index.html 引入这两个js文件
<script type="text/javascript" src="module1.js"></script>
<script type="text/javascript" src="module2.js"></script>
<script type="text/javascript">

    module1.fun()
    module1.bar()

    module2.fun()
    module2.bar()

    module1.data = 'other data'
    module1.fun()
  
</script>

命名空间模式: 对对象进行了简单的封装
作用: 这样就减少了全局的变量
问题: 这样也是不安全的行为

3. IIFE模式(立即调用函数表达式)

创建 module.js

(function (window) {
  let data = 'module'

  function fun() {
    console.log(`module.js fun() ${data}`)
  }

  function bar() {
    console.log(`module.js bar() ${data}`)
    otherFun()
  }

  function otherFun() {
    console.log('module.js otherFun()')
  }

  window.module = {fun, bar}
})(window)

index.html

<script type="text/javascript" src="module.js"></script>
<script type="text/javascript">
  module.fun()
  module.bar()
 
  module.data = 'new data'
  module.fun()

</script>

IIFE模式: 闭包,匿名函数自调用
作用: 数据是私有的, 外部只能通过暴露的方法操作
问题: 如果当前这个模块依赖另一个模块怎么办?

4. IIFE模式增强

先引入jQuery.js,创建 module.js

(function (window, $) {
  let data = 'module'

  function fun() {
    console.log(`module.js fun() ${data}`)
    $('body').css('background', 'pink')
  }

  function bar() {
    console.log(`module.js bar() ${data}`)
    otherFun()
  }

  function otherFun() {
    console.log('module.js otherFun()')
  }

  window.module = {fun, bar}
})(window, jQuery)

index.html

<script type="text/javascript" src="module.js"></script>
<script type="text/javascript">
  module.fun()
</script>

IIFE模式增强: 引入依赖
作用: 现代模块实现的基石

5. 多个js模块

当一个html页面引入了多个js模块,这也会出现很多问题,一个js依赖另一个js,这是js引入的顺序就不能调整,,并且加载也过多,导致页面会加载很慢,引入的依赖也非常的混乱,后期难以管理

这些问题,我们通过模块化很好解决,下面就正式进入模块化的学习