JavaScript模块

梁柱

概述

模块通常是指编程语言所提供的代码组织机制,利用此机制可将程序拆解为独立且通用的代码单元
模块的优点:1.可维护性;2.命名空间;3.重用代码
常见的模块化规范:CommonJSAMDCMD,也有ES6的Modules

CommonJS

CommonJS的核心思想就是通过 exports 或者 module.exports 来导出需要暴露的接口,然后通过 require 方法来同步加载所要依赖的其他模块,这个规范里,每个文件就是一个模块。

a.js
let a = 123;
let foo = function () {
    console.log("foo");
};
//两个顺序不能颠倒,否则变量a的值就无法暴露
module.exports = {
    foo: foo,
};
module.exports.a = a;
b.js
const b = require("./a.js");
console.log(b.a);
b.foo();

module.exports属性表示当前模块对外输出的接口,其他文件加载该模块,实际上就是读取module.exports变量。nodeJS为了方便,为每个模块提供一个exports变量,指向module.exports。这等同在每个模块头部,有一行这样的命令。

var exports = module.exports;

不能直接将exports变量指向一个值,等于切断了exportsmodule.exports的联系。如下:

let a = 123;
let foo = function () {
    console.log("foo");
};
//这种写法会报错
exports = {
    foo: foo,
};

注意:

  • CommonJS是同步加载模块的。
  • CommonJS是不适用于浏览器端。

浏览器端的模块,不能采用"同步加载"(synchronous),只能采用"异步加载"

客户端主要有:AMD( 实现有RequireJS ) / CMD(实现有SeaJS),随着ES6模块化规范的实现和普及,第三方的模块化实现将会慢慢的淘汰。

AMD / CMD

AMD 是 RequireJS 在推广过程中对模块定义的规范化产出
CMD是SeaJS在推广过程中对模块化定义的规范化产出
两种规范是服务于JavaScript的模块化开发,目前两种都能实现浏览器端的模块化开发的目的

不同:
AMD是预执行(提前执行),CMD是懒执行(延迟执行)。
AMD推崇依赖前置,CMD推崇就近依赖。

// AMD
define(['./a', './b'], function(a, b) {  // 依赖必须一开始就写好  注意标红的,通过函数回调的方式将引入的依赖赋值给标红的变量,然后整个块就可以利用这个引入的依赖了
   a.doSomething()   
   // 此处略去 100 行   
   b.doSomething()   
   ...
});
// CMD
define(function(require, exports, module) {
   var a = require('./a')  
   a.doSomething()  
   // 此处略去 100 行  
   var b = require('./b')
   // 依赖可以就近书写  
   b.doSomething()
   // ...
});

ES6

ES6的模块化方案是真正的规范。 在ES6中,我们可以使用 import 关键字引入模块,通过 export 关键字导出模块。export和import命令可以出现在模块的任何位置,只要处于模块顶层就可以。如果处于块级作用域内,就会报错,接下来说的import命令也是如此。
1.方式一:

let flag = true;
function sum(num1, num2) {
  return num1 + num2;
}
export { flag, sum }

//b.js
import {flag,sum} from './a.js'

2.方式二:

//a.js
export const height = 1.88;
export function mul(num1, num2) {
  return num1 * num2
}

//b.js
import {height,mul} from './a.js'

3.方式三:
某些情况下,一个模块中包含某个的功能,我们并不希望给这个功能命名,而且让导入者可以自己来命名
这个时候就可以使用export defaultexport default本质是将该命令后面的值,赋给default变量以后再默认,所以直接将一个值写在export default之后。一个模块中只能有一个export default

//a.js
export default function (argument) {
  console.log(argument);
}

//b.js
import hello from "./a.js";
hello('你好啊');

import使用

1.import命令具有提升效果,会提升到整个模块的头部,首先执行。
2.如果是在HTML代码中使用模块,引入两个js文件时需要设置为module。才能在浏览器中使用。

<script src="a.js" type="module"></script>
<script src="b.js" type="module"></script>

3.如果希望某个模块中所有的信息都导入,可以通过*导入模块中所有的export变量。通常情况下需要给*起一个别名,方便后续的使用。

//a.js
export const height = 1.88;
export function mul(num1, num2) {
  return num1 * num2;
}

//b.js
import * as a from './a.js'
console.log(a.height);
阅读 726
132 声望
9 粉丝
0 条评论
132 声望
9 粉丝
文章目录
宣传栏