小火柴的博客笔记 小火柴的博客笔记
首页
学过的习
踩过的坑
想过的事
首页
学过的习
踩过的坑
想过的事
  • 学过的习

    • CSS的样式优先级权重
    • 事件冒泡和事件捕获
    • js模块可以通过两种方式对外暴露函数
    • js中的内存泄漏和内存溢出
    • js作用域链
    • 控制台暴露vue
    • es5常用知识总结
    • es6常用知识总结
    • es7常用知识总结
    • js模块化
      • nodeJs学习
      • node搭建服务器
      • webPack学习
      • js原型对象和原型链的理解
      • css阻塞与js阻塞
      • ajax的学习
      • 浏览器的重绘与重排
      • 函数防抖与函数节流学习记录
      • 浏览器储存学习
      • React起步
      • React的基本使用
      • React项目搭建
      • vue中attrs和listeners的使用
      • js的精度问题
      • React的状态管理
      • yarn和npm的对比
      • websocket的使用
    • 想过的事

    • 踩过的坑

    • 前端
    • 学过的习
    小火柴
    目录

    js模块化

    # 一、可以暴露函数的方式:

    1、 全局函数模式: 将不同的功能封装成不同的全局函数 问题: Global被污染了, 很容易引起命名冲突,比如两个js文件暴露的函数对象命名是相同的,在HTML同时引入时,会导致命名产生冲突。

    2、 namespace模式: 简单对象封装,减少了全局变量。(用对象来暴露功能) 问题: 不安全(数据不是私有的, 外部可以直接修改)

    3、 IIFE模式: 匿名函数自调用(闭包),immediately-invoked function expression(立即调用函数表达式) 作用: 数据是私有的, 外部只能通过暴露的方法操作

    (function (window) {
      //数据
      let data = 'test'
    
      //操作数据的函数
      function foo() { //用于暴露有函数
        console.log(`foo() ${data}`)
      }
    
      function bar() {//用于暴露有函数
        console.log(`bar() ${data}`)
        otherFun() //内部调用
      }
    
      function otherFun() { //内部私有的函数
        console.log('otherFun()')
      }
    
      //暴露行为
      window.myModule = {foo, bar}
    })(window)
    

    4、IIFE模式增强 : 引入依赖,是现代模块实现的基石

    (function (window, $) {
      //数据
      let data = 'test'
    
      //操作数据的函数
      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)
    

    # 问题: 当HTML使用多个js文件时:

    1. 一个页面需要引入多个js文件
    2. 问题: 1). 请求过多,需要多个js请求 2). 依赖模糊,模块间可能会相互依赖,要求引入的顺序不能出错。 3). 难以维护

    # 二、js模块化

    js模块化是将一个复杂的程序依据一定的规则(规范)封装成几个块(文件), 并进行组合在一起,块的内部数据/实现是私有的, 只是向外部暴露一些接口(方法)与外部其它模块通信

    组成: 1、 数据--->内部的属性 2、操作数据的行为--->内部的函数 模块化: 编码时是按照模块一个一个编码的, 整个项目就是一个模块化的项目

    1、CommonJS: 暴露方式: module.exports = value 向外暴露一个对象 module.exports = value 向外暴露一个函数 exports.xxx = value 向外暴露一个对象,这种方式可以在一个js文件中暴露多个对象

    引入方式: var module = require(模块名或模块路径);

    //commonJS-test1.js
    
    module.exports = {
        name:'tom',
        age:18,
        say:function(){
            console.log('this is tom say')
        }
    }
    module.exports.otherAttr = 'other'
    
    exports.foo = function () {
      console.log('foo() ....')
    }
    
    exports.bar = function () {
      console.log('bar() .....')
    }
    
    //commonJs-test2.js
    
    let a = require('./commonJS-test1');
    console.log(a,'this is test1')
    
    //结果:{ name: 'tom', age: 18, say: [Function: say], otherAttr: 'other' } bar和foo不在其中
    
    
    
    
    //commonJS-test1.js
    
    // module.exports = {
    //     name:'tom',
    //     age:18,
    //     say:function(){
    //         console.log('this is tom say')
    //     }
    // }
    module.exports.otherAttr = 'other'
    
    exports.foo = function () {
      console.log('foo() ....')
    }
    
    exports.bar = function () {
      console.log('bar() .....')
    }
    
    //commonJs-test2.js
    
    let a = require('./commonJS-test1');
    console.log(a,'this is test1')
    
    //结果:{ otherAttr: 'other', foo: [Function (anonymous)], bar: [Function (anonymous)]}
    
    
    Node.js模块化,服务器端。运行时, 动态同步引入
      |-modules
        |-module1.js
        |-module2.js
        |-module3.js
      |-app.js
      |-package.json
        {
          "name": "commonJS-node",
          "version": "1.0.0"
        }
        
    Browserify模块化,浏览器端  也称为js的打包工具,在运行前对模块进行编译/转译/打包的处理(已经将依赖的模块包含进来了), 运行的是打包生成的js, 运行时不存在需要再从远程引入依赖模块
    
      |-js
        |-dist //打包生成文件的目录
        |-src //源码所在的目录
          |-module1.js
          |-module2.js
          |-module3.js
          |-app.js //应用主源文件
      |-index.html
      |-package.json
        {
          "name": "browserify-test",
          "version": "1.0.0"
        }
    
    
    1、module1.js
       module.exports = {
          foo() {
            console.log('moudle1 foo()')
          }
        }
    
    2、module2.js
       module.exports = function () {
          console.log('module2()')
        }
    
    3、module3.js
        exports.foo = function () {
          console.log('module3 foo()')
        }
        
        exports.bar = function () {
          console.log('module3 bar()')
        }
    
    
    4、app.js
        let module1 = require('./module1')
        let module2 = require('./module2')
        let module3 = require('./module3')
        
        let uniq = require('uniq')
        
        //使用模块
        module1.foo()
        module2()
        module3.foo()
        module3.bar()
    
    

    2、AMD-RequireJS 模块化(浏览器端) 定义暴露模块: define([依赖模块名], function(){return 模块对象}) 引入模块: require(['模块1', '模块2', '模块3'], function(m1, m2){//使用模块对象}) 配置:

            require.config({
              //基本路径
              baseUrl : 'js/',
              //标识名称与路径的映射
              paths : {
                '模块1' : 'modules/模块1',
                '模块2' : 'modules/模块2',
                'angular' : 'libs/angular',
                'angular-messages' : 'libs/angular-messages'
              },
              //非AMD的模块
              shim : {
                'angular' : {
                    exports : 'angular'
                },
                'angular-messages' : {
                    exports : 'angular-messages',
                    deps : ['angular']
                }
              }
            })
    

    3、CMD-SeaJs模块化(浏览器端) 定义暴露模块:

            define(function(require, module, exports){
              通过require引入依赖模块
              通过module/exports来暴露模块
              exports.xxx = value
            })
    

    使用模块:seajs.use(['模块1', '模块2'])

    4、ES6模块化,ES6内置了模块化 定义暴露模块 : export

    暴露一个对象: 
             export default 对象
    
    暴露多个: 
    
              export var xxx = value1
              export let yyy = value2
              或者
              var xxx = value1
              let yyy = value2
              export {xxx, yyy}
    

    引入使用模块 : import

    default模块:
            import xxx  from '模块路径/模块名'
    
    其它模块
            import {xxx, yyy} from '模块路径/模块名'
            import * as module1 from '模块路径/模块名'
    

    问题: 所有浏览器还不能直接识别ES6模块化的语法
    解决: 1、 使用Babel将ES6--->ES5(使用了CommonJS) ----浏览器还不能直接支行 2、使用Browserify--->打包处理----浏览器可以运行

    #JS
    es7常用知识总结
    nodeJs学习

    ← es7常用知识总结 nodeJs学习→

    Theme by Vdoing | Copyright © 2021-2023 X match
    • 跟随系统
    • 浅色模式
    • 深色模式
    • 阅读模式