JavaScript原始功能

  • JS作者在设计JS这门语言的时候,就只是想做一些客户端简单的判断或者操作一下html+css,没有想到JS会发展为现在三大框架的时代,那个时候写的脚本可能就是

    1. <script>
    2. doucument.getElementById('button').onClick = function () {
    3. alert('发生了点击');
    4. }
    5. </script>
  • 随着ajax异步请求的出现,慢慢形成了前后端的分离

    • 客户端需要完成的事情越来越多,代码量也是与日俱增
    • 为了应对代码量的递增,我们通常会将代码写在多个js文件中,进行维护
    • 但是这种维护方式,依然不能避免遇到一些灾难性的问题(全局变量重名,全局变量过多,变量被被人修改等等问题)

自己实现模块化的方式

  • 现在我们尝试自己来实现模块化
  • 首先,加入每个人负责一个js文件,这个js文件中要使用闭包的方式,将变量和函数都放在一个自执行函数内部,这样就不会和别人的变量起冲突了,然后我们把想要暴露出去的变量存在一个对象中,让这个自执行函数返回这个对象,这样,别人或者别的地方就可以使用我们的变量或者函数了,如下:

    1. var ModuleA = (function () {
    2. // 声明一个空对象,用于存放我们想要暴露出去的变量或函数
    3. var obj = {};
    4. var flag = true;
    5. var name = 'ryan z';
    6. var age = 23;
    7. function sum (num1, num2) {
    8. return num1 + num2;
    9. }
    10. function alert () {
    11. alert(123)
    12. }
    13. // 把我们想要暴露出去的变量或者函数赋值给obj对象
    14. obj.name = name;
    15. obj.flag = flag;
    16. obj.sum = sum;
    17. // 将这个obj对象返回出去,赋值给ModuleA
    18. return obj;
    19. })()
  • 这样这个ModuleA就是全局的变量了,里面存放了我们这个js文件想要暴露出去的东西,别的地方就可以使用了

  • 但是这种匿名函数的做法还是有一些问题,这只是一个雏形,前端已经有了一些特定的解决方式
  • 常见的模块化规范:CommonJS/AMD/CMD/ES6的Mudules

CommonJS了解

  • 模块化的核心就是:导入和导出
  • CommonJS的导出

    1. modules.exports = {
    2. flag: true,
    3. test (a, b) {
    4. return a + b
    5. },
    6. demo (a, b) {
    7. return a - b
    8. }
    9. }
  • CommonJS的导入

    1. let {test, demo, flag} from require('./muduleA.js');

ES6的模块化实现

  • ES6中避免过多全局变量的方法:在引入js文件的时候,加上一个type=”module”属性,这样这个js文件中的变量和函数外部无法访问,想象为一个房间
  • ES6导出:export { flag, name, age, sum } 或者 export let flag = true;在定义时直接导出(也可以导出函数或者对象或者类class)
  • ES6导入:import { flag } from “./aaa.js”;
  • 有的时候,一个模块中包含某个功能,但是我们并不希望给这个功能命名,且可以让导入者自己来命名,这个时候就可以使用export default
    • export default 在一个js文件中只能有一个
    • 导入时就可以 自己给默认导出的这个 起个名字 import ryan from “./aaa.js”,而且此时不用使用大括号
  • 统一全部导入:import * as aaa from “./aaa.js” ,相当于将我们导出的所有的东西都放在aaa这个对象中,可以使用aaa.flag这种方式去里面拿这些变量