Skip to main content
 首页 » 编程设计

详解ES6 模块化

2022年07月19日146sxdcgaq8080

详解ES6 模块化

本文我们学习ES6模块化,如何从模块中导出变量、函数、类并在其他模块中重用。
ES6 模块即为在严格模式下执行的JavaScript文件。意味着模块中声明的变量和函数不会自动增加至全局作用域中。

1. 浏览器中执行模块

首先创建新文件message.js并增加下列代码:

export let message = 'ES6 Modules'; 

在es6中message.js是一个模块,包含message变量。export语句暴露message变量给其他模块。

其次,创建新的文件app.js使用message.js模块。app.js模块创建h1元素并添加至html页中。import语句从message.js模块中导入message变量。

import { message } from './message.js' 
  
const h1 = document.createElement('h1'); 
h1.textContent = message 
  
document.body.appendChild(h1) 

第三步,创建新的html页面文件使用app.js模块:

<!DOCTYPE html> 
<html> 
<head> 
  <meta charset="utf-8"> 
  <title>ES6 Modules</title> 
</head> 
<body> 
<script type="module" src="./app.js"></script> 
</body> 
</html> 

注意在script标签中加载type=“module”,如果在浏览器中打开该页面,下面信息:

ES6 Modules

下面我们详细讲解导入和导出语句。

2.Es6模块化

2.1 导出

要导出变量、函数或类,需要在其前面加export关键字:

// log.js 
export let message = 'Hi'; 
  
export function getMessage() { 
  return message; 
} 
  
export function setMessage(msg) { 
  message = msg; 
} 
  
export class Logger { 
} 

log.js模块中有一个变量、两个函数和一个类,我们使用export关键字导出模块中所有标识符。
注意export关键字需要函数或类有名称,不能导出匿名函数或类。

JavaScript也支持先定义变量、函数或类,再导出:

// foo.js 
function foo() { 
   console.log('foo'); 
} 
  
function bar() { 
  console.log('bar'); 
} 
export {foo} 

上例首先定义for函数然后导出。因为没有导出bar函数,其他模块不能访问该,对其他模块来说其是私有的不能访问。

2.2 导入

一旦在模块中使用export导出外部能访问的变量、函数或类,其他模块使用import关键字进行引入,语法如下:

import { what, ever } from './other_module.js'; 
  • 使用花括号指定导入内容,称为绑定
  • 指定从哪个模块导入绑定

注意当从模块中导入绑定时,绑定行为与const关键字定义类似。意味着不能其他标识符与之同名或修改绑定的值。
请看示例:

// greeting.js 
export let message = 'Hi'; 
  
export function setMessage(msg) { 
  message = msg; 
} 

当导入message变量和setMessage函数,可以使用setMessa函数去改变message的值:

// app.js 
import {message, setMessage } from './greeting.js'; 
console.log(message); // 'Hi' 
  
setMessage('Hello'); 
console.log(message); // 'Hello'  

但不能直接改变变量message的值,下面语句编译错误:

1 
message = 'Hallo'; // error 

实际你调用setMessage函数时,JavaScript回到greeting.js模块中执行代码修改message变量值,其他改变自动反应至导入的绑定变量message。

在app.js中的绑定变量message是局部变量,因此在两个模块中的message并不相同。

  • 导入单个绑定

假如模块中有foo变量如下:

// foo.js 
export foo = 10; 

另一个模块能使用foo变量:

// app.js 
import { foo } from './foo.js'; 
console.log(foo); // 10; 

然而,你不能改变foo的值,如果修改则编译错误:

foo = 20; // throws an error 
  • 导入多个绑定

定义cal.js模块:

// cal.js 
export let a = 10, 
           b = 20, 
           result = 0; 
  
export function sum() { 
  result = a + b; 
  return result; 
} 
  
export function multiply() { 
  result = a * b; 
  return result; 
} 

你想从cal.js模块中导入这些绑定,可以显示列举:

import {a, b, result, sum, multiply } from './cal.js'; 
sum(); 
console.log(result); // 30 
  
multiply(); 
console.log(result); // 200 
  • 导入全部模块作为对象

使用型号可以导入模块所有内容作为单个对象:

import * as cal from './cal.js'; 

示例中从cal.js模块中导入所有绑定作为单个对象,则所有绑定作为cal对象属性,访问示例:

cal.a; 
cal.b; 
cal.sum(); 

这个导入也称为命名空间导入。
特别需要注意的是import语句即使使用多次仅执行一次,示例:

import { a } from './cal.js'; 
import { b } from './cal.js'; 
import {result} from './cal.js'; 

第一个import语句之后,cal.js语句已执行并加载至内存,后续import语句会重用已载入内容。

2.3. import和export限制

注意import和export语句必须在其他语句和函数的外面。下面语句编译错误:

if( requiredSum ) { 
   export sum; 
}   

同样下面语句也错误:

function importSum() { 
   import {sum} from './cal.js'; 
} 

因为两者都在其他语句之内。

2.4. 别名

JavaScript允许在导入或导出时创建别名。下面math.js模块:

// math.js   
function add( a, b ) { 
   return a + b; 
} 
  
export { add as sum }; 

在导出时add使用as关键字增加别名为sum。

因此在导入add函数时必须使用sum代替:

import { sum } from './math.js'; 

在导入时也可以使用as关键字指定别名:

import {sum as total} from './math.js'; 

2.5. 重新导出绑定

也可以对导入绑定重新导出:

import { sum } from './math.js'; 
export { sum }; 

在示例从math.js模块导入sum,然后再重新导出。等价语句为:

export {sum} from './math.js'; 

在重新导出之前需重新命名绑定可使用as关键字。请看下面示例:

export { sum as add } from './math.js'; 

也可以导出其他模块所有绑定,使用星号:

export * from './cal.js'; 

2.6. 无绑定导入

有时你想开发不导出任何内容的模块,举例给内置Array对象增加新的方法:

// array.js 
if (!Array.prototype.contain) { 
  Array.prototype.contain = function(e) { 
    // contain implementation 
    // ... 
  } 
} 

现在可以导入该模块,无需任何绑定并使用contain()方法:

import './array.js'; 
[1,2,3].contain(2); // true 

2.7. 缺省导出

模块有仅只有一个缺省导出。缺省导出方便导入使用。模块缺省导出可以使用变量、函数或类,下面是sort.js模块的缺省导出:

// sort.js 
export default function(arr) { 
  // sorting here 
}  

注意无需给函数指定名称,默认使用模块名称作为函数名称。

import sort from sort.js; 
sort([2,1,3]); 

你看到sort表示表示sort.js模块的缺省函数,我们不能对sort标识符使用{}。

下面修改sort.js模块增加非缺省函数:

// sort.js 
export default function(arr) { 
  // sorting here 
} 
export function heapSort(arr) { 
  // heapsort 
} 

导入两个绑定可以使用绑定列表,规则如下:

  • 确定绑定必须在首位
  • 非缺省绑定必须使用花括号
import sort, {heapSort} from './sort.js'; 
sort([2,1,3]); 
heapSort([3,1,2]); 

从命名缺省导出可以使用as关键字:

import { default as quicksort, heapSort} from './sort.js'; 

3. 总结

本文我们学习ES6模块,如何从模块中导出绑定以及在其他模块中引入。


本文参考链接:https://blog.csdn.net/neweastsun/article/details/104060748