美文网首页
ES6之用模块封装代码

ES6之用模块封装代码

作者: 27亿光年中的小小尘埃 | 来源:发表于2019-12-22 01:23 被阅读0次

    什么是模块?

    模块( Modules )是使用不同方式加载的 JS文件(与JS原先的脚本加载方式相对)。这种不同模式很有必要,因为它与脚本( script )有大大不同的语义:

    • 模块代码自动运行在严格模式下,并且没有任何办法跳出严格模式;
    • 在模块的顶级作用域创建的变量,不会被自动添加到共享的全局作用域,它们只会在模块顶级作用域的内部存在;
    • 模块顶级作用域的 this 值为 undefined ;
    • 模块不允许在代码中使用 HTML 风格的注释(这是 JS 来自于早期浏览器的历史遗留特性);
    • 对于需要让模块外部代码访问的内容,模块必须导出它们;
    • 允许模块从其他模块导入绑定。

    基本的导出

    你可以使用 export 关键字将已发布代码部分公开给其他模块。最简单方法就是将export放置在任意变量、函数或类声明之前,从模块中将它们公开出去:

    // 导出数据
    export var color = "red";
    export let name = "Nicholas";
    export const magicNumber = 7;
    // 导出函数
    export function sum(num1, num2) {
        return num1 + num1;
    }
    // 导出类
    export class Rectangle {
        constructor(length, width) {
            this.length = length;
            this.width = width;
        }
    }
    // 此函数为模块私有
    function subtract(num1, num2) {
        return num1 - num2;
    }
    // 定义一个函数……
    function multiply(num1, num2) {
        return num1 * num2;
    }
    // ……稍后将其导出
    export { multiply };
    

    要求:

    • 导出的函数声明与类声明必须要有名称

    基本导入

    import { sum, multiply } from "./example.js";    
    

    import后面的括号里写上需要导入到方法名,多个用','号隔开

    要求:

    • 你对同一个模块使用了多少次 import 语句,该模块都只会被执行一次。

    完全导入一个模块

    还有一种特殊情况,即允许你将整个模块当作单一对象进行导入,该模块的所有导出都会作为对象的属性存在。例如:

    // 完全导入
    import * as example from "./example.js";
    console.log(example.sum(1,
    example.magicNumber)); // 8
    console.log(example.multiply(1, 2)); //
    

    重命名导出与导入

    你可能并不想使用从模块中导出的变量、函数或类的原始名称。假设你想用不同的名称来导出一个函数,你可以使用 as 关键字来指定新的名称,以便在模块外部用此名称指代目标函数

    function sum(num1, num2) {
        return num1 + num2;
    }
    export { sum as add };
    

    此处的 sum() 函数被作为 add() 导出,前者是本地名称( local name ),后者则是导出名称( exported name )。这意味着当另一个模块要导入此函数时,它必须改用 add 这个名称:

    import { add } from "./example.js
    

    导入默认值

    你可以使用如下语法来从一个模块中导入默认值:

    // 导入默认值
    import sum from "./example.js";
    console.log(sum(1, 2)); // 3
    

    对于既导出了默认值、又导出了一个或更多非默认的绑定的模块,你可以使用单个语句来入它的所有导出绑定。例如,假设你有这么一个模块:

    export let color = "red";
    export default function(num1, num2) {
        return num1 + num2;
    }
    
    

    导入:

    import sum, { color } from "./example.js";
    console.log(sum(1, 2)); // 3
    console.log(color); // "red"
    
    

    绑定的再导出

    export { sum } from "./example.js";
    
    

    无绑定的导入

    有些模块也许没有进行任何导出,相反只是修改全局作用域的对象。尽管这种模块的顶级变量、函数或类最终并不会自动被加入全局作用域,但这并不意味着该模块无法访问全局作用域。诸如Array与Object之类的内置对象的共享定义在模块内部是可访问的,并且对于这些对象的修改会反映到其他模块中。

    例如,若你想为所有数组添加一个 pushAll() 方法,你可以像下面这样定义一个模块:

    // 没有导出与导入的模块
    Array.prototype.pushAll = function(items) {
        // items 必须是一个数组
        if (!Array.isArray(items)) {
            throw new TypeError("Argument must be an array.");
        }
        // 使用内置的 push() 与扩展运算符
        return this.push(...items);
    };
    
    

    这是一个有效的模块,尽管此处没有任何导出与导入。此代码可以作为模块或脚本来使用。由于它没有导出任何东西,你可以使用简化的导入语法来执行此模块的代码,而无须导入任何绑定:

    import "./example.js";
    let colors = ["red", "green", "blue"];
    let items = [];
    items.pushAll(colors);
    

    相关文章

      网友评论

          本文标题:ES6之用模块封装代码

          本文链接:https://www.haomeiwen.com/subject/qgwnnctx.html