• ES6模块


    一、为什么需要模块

    起初,项目的代码量不大时,常把所有代码写在一个文件中。随着代码量的不断增加,这样做会带来两个问题:一、不利于分工合作;二、不利于后期维护。因此,需要依据代码功能把代码从一个文件拆分到不同的文件。但是,现在又产生一个新的问题,多个文件的变量都位于全局作用域中,很容易产生冲突,为了解决这个问题,就有了模块。

    最初,ES标准中还没有模块和模块系统的支持,只能通过立即执行函数来模拟模块的功能。具体做法是:把不同文件中的代码都放在立即执行函数中,然后把可能会被其他代码使用的变量、函数、类通过全局对象的属性暴露出去。如下代码所示:

    (function() {
    	class Person {
    		constructor(name, age) {
    		this.name = name;
    		this.age = age;
    		}
    	}
    
    	window.Person = Person;
    })();
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    通过立即执行函数模拟的模块,大大减少了全局变量,但是依然存在不少通过全局对象属性暴露的变量,例如,window.Person = Person;,更大的问题是,我们需要手动管理加载文件的顺序,例如,文件A中的类继承了文件B中的类,那么在HTML文件中, 必须先于 引入,如果存在大量的复杂的依赖关系,手动管理依赖是非常困难的。这是立即执行函数模拟(实现)模块存在的两个主要问题。

    下文中介绍的ES6中引入的模块和模块系统,会解决立即执行函数模拟模块存在的问题~~

    二、 模块和模块系统

    1、 模块
    模块是局部作用域代码块

    在ES6中一个模块本质是一个文件

    2、模块系统

    模块系统主要解决问题:

    • 模块化
    • 消除全局变量
    • 管理加载顺序

    以前,ES还没有提供模块的原生支持时,第三方JS库,例如,RequireJS、SeaJS等实现模块系统的功能。

    在HTML代码中引入一个模块的方式

    <script src="file.js" type="module">script>
    
    • 1

    比起一般的引入方式,多了一个type属性,属性值module表示以模块的方式引入文件。如果不添加属性"type="module,那么,文件以普通的方式引入,文件中的变量会作为全局变量处理。

    什么时候或场景需要把文件以模块方式引入呢?
    当文件中出现import或export关键字时。

    三、模块的两种导入和导出

    一个模块没有导出,也可以导入。只是将模块中的代码执行一遍,没有暴露任何变量

    1、export default 导出和对应的import导入

    export default 表达式; 
    
    • 1

    表达式:基本类型的字面量,变量,函数和类的表达式。函数和类表达式可以匿名。

    export default 1;
    
    • 1
    export default function(){};
    
    • 1
    export default class{}
    
    • 1
    const str = 'hello';
    export default str;
    
    • 1
    • 2

    一个模块只能定义一个exprot default,不能导出多个。

    export default 1;
    export default 'hello';
    
    • 1
    • 2

    会出现报错:

    在这里插入图片描述

    2、exprot导出和对应的improt导入语法

    基本语法

    方式一:export 声明语句;
    export let/const/var variable = value;
    export function foo(){}
    exprot class Clz{}
    方式二:先声明后export{变量名}
    let variable = value;
    exprot {variable};

    注意 普通变量、函数和类表达式不能匿名。不能是基本类型值。

    import {variable} from XXX.js

    导出导入多个

    利用基本语法方式二

    const variable = value;
    function  foo() {}
    class Clz {}
    
    // 导出多个
    export {variable, foo, Clz};
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    导出导入起别名

    export {variable as username}
    
    • 1

    导入的”角色“的名字和我当前代码冲突,就可以别名

    import {Clz as Person}
    
    • 1

    整体导入
    包括export default导出的角色

    import * as obj from 'module.js';
    
    • 1

    同时导入

    import {variable, foo, Clz} from ‘module.js’
    import def from ‘module.js’

    export和exprot default可以同时导出,不过export default必须在最前面先导出,
    import def, {variable, foo, Clz } from ‘module.js’

    也可以分开导入
    import def from ‘module.js’
    import {variable, foo, Clz } from ‘module.js’

    想法
    export 对标Java中的public
    没有export 对标Java中的private

    四、其他注意事项

    1、模块本身作用域中的this指向undefined

    应用,可以在文件首部添加以下代码,来提示用户应该以为模块的方式应用文件

    if (typeof this !== 'undefined') {
        throw new Error('请以模块方式引入该文件');
    }
    
    • 1
    • 2
    • 3

    2、 import关键字和import()函数

    import和export 命令会先于其他代码执行,和它所在的位置无关。因此,我们应该把它们放在模块的首部,而不是代码块,例如if代码块中。

    import() 可以实现条件导入,即满足某些条件,例如,是否是PC端、移动端,而导入不同的模块。

    此函数不是标准,只是提案。可以配合webpack解决兼容性问题。

    3、 导入导出的复合写法

    在这里插入图片描述

    五、 总结

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    表达式包括基本类型值字面量或变量,函数、类表达式,可以匿名

    在这里插入图片描述
    声明即变量的声明;语句即表达式,包括变量,函数或者类的声明。

    在这里插入图片描述

  • 相关阅读:
    【560. 和为 K 的子数组】
    金融时间序列预测方法合集:CNN、LSTM、随机森林、ARMA预测股票价格(适用于时序问题)、相似度计算、各类评判指标绘图(数学建模科研适用)
    【Vue 开发实战】基础篇 # 12:常用高级特性provide/inject
    Vega Prime入门教程12.10:DevToolCRO与部署
    15 款 PDF 编辑器帮助轻松编辑、合并PDF文档
    5. Spring Boot配置绑定
    长时间序列遥感数据处理及在全球变化、物候提取、植被变绿与固碳分析、生物量估算与趋势分析等领域中的应用
    python基础(二、基础语法)
    图解机器学习 | 降维算法详解
    GCC 编译器
  • 原文地址:https://blog.csdn.net/gao_zhennan/article/details/126673832