JavaScript 模块化规范

在学习 JavaScript 模块化规范之前,我们应该想一下什么是模块?为什么我们要使用模块化?

什么是模块

模块是比对象和函数更大的代码单元,使用模块可以将程序进行归类,也就是说可以将一个复杂的程序依据一定规则(规范)封装成几个块(文件),并进行组合在一块的内部数据/实现私有的,只是向外暴露一些接口(方法)与外部其他模块通信。一般一个.js文件就是一个模块。

模块化

编码时时按照模块一个一个编码的,整个项目就是一个模块化的项目

模块化的进化过程

全局function模式:
* module1.js

let data = 'testdata'
    //操作数据的函数
    function foo() {
      console.log(`foo() ${data}`)
    }
    function bar() {
      console.log(`bar() ${data}`)
    }

  * module2.js

    let data2 = 'other data'
    function foo() {    //与上面 module1.js 模块中的函数冲突了
      console.log(`foo() ${data2}`)
    }

说明:

  • 全局函数模式:将不同的功能封装成不同的全局函数
  • 问题:全局变量被污染了,容易引起命名冲突
namespace模式: 简单对象封装
* module1.js
    let myModule = {
      data: 'testdata',
      foo() {
        console.log(`foo() ${this.data}`)
      },
      bar() {
        console.log(`bar() ${this.data}`)
      }
    }
    
  * module2.js
    let myModule2 = {
      data: 'testdata',
      foo() {
        console.log(`foo() ${this.data}`)
      },
      bar() {
        console.log(`bar() ${this.data}`)
      }
    }

通过添加命名空间的形式从某种程度上解决了变量命名冲突的问题,但是并不能凶根本上解决这个问题。
说明:

  • 作用:将数据/行为封装到对象中,解决了命名冲突(减少了全局变量)
  • 问题:数据不安全,暴露了所有的模块成员,内部状态可以被外部改写。
IIFE模式: 匿名函数自调用(闭包)
 module3.js
    (function (window) {
      //数据
      let data = 'testdata'
      //操作数据的函数
      function foo() { //用于暴露有函数
        console.log(`foo() ${data}`)
      }
      function bar() {//用于暴露有函数
        console.log(`bar() ${data}`)
        otherFun() //内部调用
      }
      function otherFun() { //内部私有的函数
        console.log('otherFun()')
      }
    
      //暴露行为
      window.myModule = {foo, bar}
    })(window)

说明:

  • IIFE : immediately-invoked function expression(立即调用函数表达式)
  • 作用:将数据和行为封装到一个函数内部,通过给 window 添加属性来向外暴露接口
  • 问题:如果当前这个模块依赖另一个模块怎么办?
IIFE模式增强 : 引入依赖
* 引入jquery到项目中
  * module4.js
    ```
    (function (window, $) {
      //数据
      let data = 'atguigu.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)
  1. 页面加载多个js的问题
  • 页面:
    <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>
    

说明:

  • 一个页面需要引入多个js文件
  • 问题:
    1、请求过多
    2、依赖模糊
    3、难以维护

模块化规范

  • 服务器端规范主要是 CommonJS
  • 浏览器端:Browserify,也称为js的打包工具
  • 客户端规范主要有:AMD、CMD。AMD规范的实现主要有 RequireJS;CMD规范主要实现有SeaJS。
CommonJS

基本语法:

定义暴露模块 : exports
     exports.xxx = value  //value  可以是任意数据类型
     module.exports = value
引入模块 : require
     var module = require('模块名/模块相对路径')	

exports.xxx 和module.exports的实际作用是一样的,但是可以多次使用前者在同一个文件中向外暴露属性,而后者若是多次使用,则最后一个使用module.exports暴露的属性将会覆盖前面定义的所有 module.exports暴露的属性。

AMD

首先我们需要下载 require.js, 并引入;官网: http://www.requirejs.cn/
基本语法:

定义暴露模块: define([依赖模块名], function(){return 模块对象})
引入模块: require(['模块1', '模块2', '模块3'], function(m1, m2){//使用模块对象})
      * 配置: 
        require.config({
          //基本路径 
          baseUrl : 'js/',
          //标识名称与路径的映射
          paths : {
            '模块1' : 'modules/模块1',
            '模块2' : 'modules/模块2'
          }
       })

AMD的

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值