• javascript复习之旅 13.1 模块化(上)


    start

    • 记录发展历程

    1. 一个单一的JS文件

    一开始需求比较简单,快速写一个 js 脚本来实现一个功能。

    例如:

    // 1.js
    var tomato = '我是番茄'
    
    /* ....功能代码 */
    
    • 1
    • 2
    • 3
    • 4

    随着功能日益增多,代码量也随之增多,随之而来的就会出现这些问题:

    1. 所有代码在一个文件中,编写代码不方便;
    2. 命名冲突;

    2.多个JS文件

    按功能,按类别,按规范,将一个 js 文件拆分成多个 js 文件。

    这种做法解决了所有代码都存储在一个文件的问题,但是依旧会出现命名冲突的问题。

    例如:

    DOCTYPE html>
    <html lang="en">
    <body>
      <script src="./1.js">script>
      <script src="./2.js">script>
    
      <script>
        console.log('打印最新的tomato字段', tomato)
        // 打印最新的tomato字段 ƒ tomato() {
        //   console.log('函数tomato')
        // }
      script>
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    // 1.js
    var tomato = '字符串'
    console.log(tomato)
    
    // 2.js
    function tomato() {
      console.log('函数tomato')
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    遗留问题:

    • 命名冲突

    3.命名空间(namespace)

    为了解决命名冲突的问题又这么一个方案:命名空间

    简单理解,就是把变量名放在对象中,简单的对象封装。

    例如

    var bear = {
      color: '',
      name: '',
      size: '',
      shape: '',
      say: function() {
        console.log('嗷')
      }
    }
    
    // 使用的时候
    bear.color="red"
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    这个方案一定程度上减少了命名重复的情况,但是这种方案还是存在问题:命名空间内部数据可以被外部随意修改

    问题

    • 外部可以直接修改内部的数据

    4.立即执行函数 IIFE

    ES6之前,仅函数存在块级作用域。所以可以利用 立即执行函数 把数据私有。

    ;(function (window) {
      let str = 'tomato777'
      function foo() {
        console.log(`foo() ${str}`)
      }
    
      function bar() {
        console.log(`bar() ${str}`)
        otherFun()
      }
    
      function otherFun() {
        console.log('otherFun()')
      }
      window.myModule = { foo, bar }
    })(window)
    
    console.log('myModule', myModule)
    // {foo: ƒ, bar: ƒ}
    
    console.log('myModule.str', myModule.str)
    // undefined
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    通过立即执行函数,我们可以实现数据私有,其次这里为了暴露数据,接收了一个形参。

    但是有时候我们代码需要使用到其他第三方库,例如 jQuery,该怎么办?

    问题

    • 文件之间的依赖如何处理

    5.文件与文件之间的依赖

    文件比较少的情况下,我们可以这样:

    index.html

    DOCTYPE html>
    <html lang="en">
    
    <head>
      <meta charset="UTF-8">
      <meta http-equiv="X-UA-Compatible" content="IE=edge">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Documenttitle>
    head>
    
    <body>
      <h1>h1中的内容h1>
      <div>
        其他内容
      div>
    
      <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js">script>
      <script src="./1.js">script>
    
      <script>
        myModule.say()
        myModule.setColor()
      script>
    
    body>
    
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    1.js

    ;(function (window, $) {
      let str = 'tomato777'
      function say() {
        console.log(`打印传入的第三方库 jquery${$}`)
      }
    
      function setColor() {
        $('h1').css('color', 'tomato')
      }
    
      window.myModule = { say, setColor }
    })(window, jQuery)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    在这里插入图片描述

    上述案例仅依赖 jQuery,所以我可以手动的去导入依赖,去调整