一、模块化进化史

全局function模式

举例

  • module1.js
//数据
let data = 'module1_data'
//操作数据的函数
function foo() {
  console.log(`foo() ${data}`)
}
function bar() {
  console.log(`bar() ${data}`)
}
  • module2.js
let data2 = 'module2_data';
function foo() {  //与另一个模块中的函数冲突了
  console.log(`foo() ${data2}`)
}
  • test1.html
<script type="text/javascript" src="module1.js"></script>
<script type="text/javascript" src="module2.js"></script>
<script type="text/javascript">
  foo() //foo() module2_data
  bar() //bar() module1_data
  let data = "修改后的数据" //error
</script>

说明

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

namespace模式

举例

  • module1.js
let myModule1 = {
  data: 'myModule1 ',
  foo() {
    console.log(`foo() ${this.data}`)
  },
  bar() {
    console.log(`bar() ${this.data}`)
  }
}
  • module2.js
let myModule2 = {
  data: 'myModule2',
  foo() {
    console.log(`foo() ${this.data}`)
  },
  bar() {
    console.log(`bar() ${this.data}`)
  }
}
  • test2.html
<script type="text/javascript" src="module2.js"></script>
<script type="text/javascript" src="module22.js"></script>
<script type="text/javascript">
  myModule1.foo() //foo() myModule1
  myModule1.bar() //bar() myModule1

  myModule2.foo() //foo() myModule2
  myModule2.bar() //bar() myModule2

  myModule1.data = 'other data' //能直接修改模块内部的数据
  myModule1.foo() //foo() other data
</script>

说明

  • namespace模式: 简单对象封装
  • 作用: 减少了全局变量
  • 问题: 不安全

IIFE模式

举例

  • module1.js
(function (window) {
  //数据
  let data = 'IIEF'

  //操作数据的函数
  function foo() { //用于暴露有函数
    console.log(`foo() ${data}`)
  }

  function bar() {//用于暴露有函数
    console.log(`bar() ${data}`)
    otherFun() //内部调用
  }

  function otherFun() { //内部私有的函数
    console.log('otherFun()')
  }

  //暴露行为
  window.myModule = {foo, bar}
})(window)
  • test3.html
<script type="text/javascript" src="module.js"></script>
<script type="text/javascript">
  myModule.foo()
  myModule.bar()
  //myModule.otherFun()  //myModule.otherFun is not a function
  console.log(myModule.data) //undefined 不能访问模块内部数据
  myModule.data = 'xxxx' //不是修改的模块内部的data
  myModule.foo() //没有改变
</script>

说明:

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

IIFE模式增强

举例

  • 引入jquery到项目中
  • module4.js
(function (window, $) {
  //数据
  let data = 'module4'

  //操作数据的函数
  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)
  • test4.html
<script type="text/javascript" src="jquery-1.10.1.js"></script>
<script type="text/javascript" src="module4.js"></script>
<script type="text/javascript">
  myModule.foo()
</script>

说明

  • IIFE模式增强 : 引入依赖
  • 这就是现代模块实现的基石

不足

<script type="text/javascript" src="module1.js"></script>
<script type="text/javascript" src="module2.js"></script>
<script type="text/javascript" src="module3.js"></script>
<script type="text/javascript" src="module4.js"></script>
  • 请求过多
  • 依赖模糊
  • 难以维护

解决方法

使用现代模块化编码和项目构建

posted @ 2020-01-14 16:46  KevinTseng  阅读(147)  评论(0编辑  收藏  举报