首页 > 其他分享 >前端模块化

前端模块化

时间:2023-10-26 11:12:54浏览次数:31  
标签:console log 模块化 前端 js flag var sum

1.为什么要有模块化

  1. 在网页开发的早期,js制作作为一种脚本语言,做一些简单的表单验证或动画实现等,那时候的代码还是很少的。
  2. 随着ajax异步请求的出现,慢慢的形成了前后端分离客户端需要完成的事情越来越多,代码量也与日俱增为了应对代码量的剧增,我们通常会将代码组织在多个js文件中,进行维护。但是这种维护方式,依然不能避免一些灾难性的问题。
  3. 比如全局变量同名问题:a文件中具有flag变量,b文件中也具有flag变量,如果此时不知道a文件中也使用flag变量的话,就会导致卡很长时间的bug。(看下面例子)
  4. 另外,这种代码编写方式对js文件的依赖顺序几乎是强制性的。
    1. 但是当js文件过多,比如有几十个的时候,弄清楚他们的顺序是一件比较耗时的事情。
    2. 而且即使弄清楚顺序,也不能避免上面出现的这种尴尬问题的发生。
ps:小明开发有aaa.js、mmm.js文件;小红开发有bbb.js
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>Document</title>
</head>
<body>
    <!-- 
        项目组长
        小明
        小红
     -->
     <script src="main.js"></script>
     <script src="aaa.js"></script>
     <script src="bbb.js"></script>
     <script src="mmm.js"></script>
</body>
</html>
aaa.js
// 小明

var name = "小明";
var age = 22;

function sum(num1, num2) {
    return num1 + num2
}

var flag = true;

if(flag) {
    console.log('sum(20, 30)', sum(20, 30));
}
bbb.js
// 小红
var name = "小红";
var flag = false;
console.log("name====", name);
mmm.js
if(flag) {
    console.log('小明的另一个文件也需要输出!!!');
}

ps:从上面可以看出,flag变量,小明声明是为true,然后小明想在mmm.js文件中也想使用flag为true这个变量,但是他不知道他的另一个成员小红也声明这个变量并且赋值为了false,导致小明需要一直调试程序,即使知道在这个文件,也需要花很长时间去研究小红的逻辑代码,因为真实的开发过程中,代码量会很多的,所以会导致全局变量同名问题

2.模块化的雏形

众所周知:闭包能够有效的解决变量同名问题,因为闭包会形成自己的作用域。

下面是修改后的文件(ps:小明开发有aaa.js、mmm.js文件;小红开发有bbb.js)

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>Document</title>
</head>
<body>
    <!-- 
        项目组长
        小明
        小红
     -->
     <script src="main.js"></script>
     <script src="aaa.js"></script>
     <script src="bbb.js"></script>
     <script src="mmm.js"></script>
</body>
</html>
aaa.js
// 小明
var moduleA = (function() {
    var name = "小明";
    var age = 22;
    function sum(num1, num2) {
        return num1 + num2;
    }
    var flag = true;
    if(flag) {
        console.log('sum(20, 30)', sum(20, 30));
    }
})()
bbb.js
// 小红
var moduleB = (function() {
    var name = "小红";
    var flag = false;
    console.log("name====", name);
})();
mmm.js
if(moduleA.flag) {
    // 1. 小明想使用他自己的flag
    // 2. 使用sum函数
}

ps:从上面通过闭包修改后,发现flag变量不能公用了,因为闭包形成作用域后,外部将不能直接使用。那如果要既不存在全局同名问题,又能共用,下面修改如下
aaa.js
// 小明
var moduleA = (function() {
    var name = "小明";
    var age = 22;
    const obj = {}; // 导出的对象
    function sum(num1, num2) {
        return num1 + num2;
    }
    var flag = true;
    if(flag) {
        console.log('sum(20, 30)', sum(20, 30));
    }
    obj.flag = flag;
    obj.sum = sum;
    
    return obj;
})()
bbb.js
// 小红
var moduleB = (function() {
    var name = "小红";
    var flag = false;
    var tip = "标识是使用小红的变量";
    var obj = {}; // 导出的对象
    obj.name = name;
    obj.flag = flag;
    obj.tip = tip;
    return obj;
})();
mmm.js
// 小明
if(moduleA.flag) {
    // 1. 小明想使用他自己的flag
    console.log('使用aaa文件中的flag', moduleA.flag);
    // 2. 使用sum函数
    console.log("moduleA.sum(100, 88)====", moduleA.sum(100, 88));
}
ps:可以看到使用一个变量obj保存后,return出去,通过控制每个模块的名称(moduleA、moduleB...)就好,项目成员之间形成约定,就能解决全局变量同名和闭包导致的不能共享问题。比如:此时小红又建了一个nnn.js文件,此时需要使用moduleA、moduleB模块的变量都是可以的。如下。  
nnn.js
console.log('使moduleA的flag', moduleA.flag);
console.log('使moduleA的sum', moduleA.sum(66,66));
console.log('使moduleB的flag', moduleB.flag);
console.log('使moduleB的tip', moduleB.tip);

3.ES6的模块化实现

众所周知,前端模块化的方式有很多种,比如CommonJS、AMD、CMD以及Es6模块的模块化,这里主要介绍ES6的模块

3.1 export的基本使用

export 指令用于导出变量,比如下面的代码

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>Document</title>
</head>
<body>
    <!-- 
        项目组长
        小明
        小红
     -->
     <script src="aaa.js" type="module"></script>
     <script src="bbb.js" type="module"></script>
     <script src="mmm.js" type="module"></script>
</body>
</html>

要使用es6的导入导出模板,则需要再script标签上添加type="module"属性

aaa.js

// 小明
var name = "小明";
var age = 22;
function sum(num1, num2) {
    return num1 + num2;
}
var flag = true;
if(flag) {
    console.log('sum--aaa', sum(20, 30));
}

// 导出方式1
export { flag, sum }

// 导出方式2
// 在定义变量的时候直接导出
export var num1 = 1000;
export var height = 1.88;

 mmm.js

// 1.导出{}中定义的变量
import { flag, sum } from "./aaa.js"
if(flag) {
    console.log('小明真是个天才哈哈哈哈哈!!');
    console.log('sum--mmm', sum(90, 9));
}

// 2. 直接导入export定义的变量
import { num1, height } from "./aaa.js"
console.log("height====", height);
console.log("num1====", num1);

3.2导出函数/类

aaa.js

// 导出函数/类
export function mul(num1, num2) {
    return num1*num2
}
export class Person {
    constructor(name, age) {
        this.name = name;
        this.age = age
    }
    run() {
        console.log(`${this.age}岁的${this.name}在奔跑`);
    }
}

 mmm.js

// 3. 导入export中的function/class
import { mul, Person } from "./aaa.js"
console.log("mul====", mul(30, 40));

new Person("大爷", 18).run();

 3.3 export default 默认导出

aaa.js

const address = "广州市";
export default address; // 切记:默认导出只能导出一个,不能导出多个

mmm.js

// 4. 导入 export default
import address from "./aaa.js"; // 切记默认导入不需要{}
console.log("address====", address); 

3.4 统一全部导入

import * as aaa from "./aaa.js"

console.log('height-统一导入的使用', aaa.height);
console.log('sum-统一导入的使用', aaa.sum(1,1));
console.log('mul-统一导入的使用', aaa.mul(2,1));

标签:console,log,模块化,前端,js,flag,var,sum
From: https://www.cnblogs.com/Qqhx/p/17785399.html

相关文章

  • 027前端CMS ghost安装
    一、安装命令如下sudoadduserghostsudousermod-aGsudoghostsu-ghostcd/data/fe-doc-centercurl-o-https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh|bashnvminstallv18.17.1npmconfigsetregistryhttps://registry.npm.taobao.orgn......
  • 23.10.25(前端页面输入框的各种操作1)
    <tr><%--限制必须输入,学号限制位数、前四位必须是2023,性别限制男或女,专业用下拉框--%><th>姓名</th><inputtype="text"name="name"required><th>学号</th><inputtype="text"name="number"requ......
  • 23.10.25(前端页面输入框的各种操作2)
    <scripttype="text/javascript"><!--全选的方法--><--复选框的定义方法以及全选方法-->functionselectAll(){vars=document.getElementsByName("like");for(vari=0;......
  • 前端面试题:原型 / 构造函数 / 实例
    1、原型/构造函数/实例原型(prototype): 一个简单的对象,用于实现对象的继承构造函数:可通过new来新建一个对象的函数实例:通过构造函数和new创建出的对象实例通过__proto__指向原型通过constructor指向构造函数缺个图?实例上......
  • 记录--纯前端也可以实现「用户无感知录屏」
    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助前言要在JavaScript中实现屏幕录制,可以使用navigator.mediaDevices.getDisplayMedia()方法来获取屏幕的媒体流。然后,可使用MediaRecorder对象将媒体流录制为视频文件。但该方法会在浏览器弹出一个授权窗口,......
  • 前端面试题:数组、字符串方法
    数组1、push:末尾添加元素,改变原数组2、pop:删除并返回最后一个元素,改变原数组3、unshift:  开头添加一个元素,改变原数组4、shift:删除第一项,改变原数组5、concat:合并数组并生成一个新数组,不改变原数组6、join:  把......
  • 【前端开发】基于vue+elemnt-ui流程图设计器解决方案
    前言越来越多的企业都在研发低代码平台,其中流程引擎是核心之一,拥有一个可以拖拽设计审批流程的设计器是相当重要的。介绍审批流程设计器是一种工具,用于创建和设计审批流程。它通常是一个可视化的设计器界面,可以方便地添加和配置审批节点、终审节点、消息节点等,并能够通过连线将......
  • 前端Chrome调试技巧最全汇总
    https://juejin.cn/post/724811804958431647200、基础操作汇总操作类型快捷键/说明切换浏览器标签......
  • 前端知识总结
    第一个前端程序两步完成一个网页程序第一步:使用记事本,编写代码在E盘下保存路径E:/itbaizhan/...,文件名Welcome.html<html> <head> <title>我的网页</title> </head> <body> Hello,我的第一个网页 </body></html>注意事项文件后缀名以.html结尾在编写代码的过程中,<>必须是......
  • C# 加密–RSA前端与后台的加密&解密
    1.在线RSA加密,选用PKCS#1来生成公钥与私钥  http://web.chacuo.net/netrsakeypair2.下载前端JS框架http://travistidwell.com/jsencrypt/3.流程图 加解密过程:先从网站上生成publicKey与privateKey第一步返回publicKey前端,用来对password等敏感字段的加密。......