ES模块语法详解
ES6(ECMAScript 2015)引入了模块系统,这是JavaScript语言层面的模块化方案。下面我将详细讲解ES模块的语法和使用方法。
基本概念
ES模块允许你将代码分割成多个独立文件,每个文件可以导出特定的功能,并在其他文件中导入使用。这种模块化方式使得代码更易于维护、重用和测试。
核心语法
1. 命名导出 (Named Exports)
javascript
// 方式1: 声明时直接导出 export const name = 'value'; export function myFunction() { /* ... */ } export class MyClass { /* ... */ } // 方式2: 声明后统一导出 const name = 'value'; function myFunction() { /* ... */ } class MyClass { /* ... */ } export { name, myFunction, MyClass }; // 方式3: 重命名导出 export { name as newName, myFunction as func };
2. 默认导出 (Default Export)
javascript
// 每个模块只能有一个默认导出 export default function() { /* ... */ } // 或 export default class MyClass { /* ... */ } // 或 const value = 'something'; export default value;
3. 导入语法
javascript
// 导入命名导出 import { name, myFunction } from './module.js'; // 重命名导入 import { name as newName } from './module.js'; // 导入默认导出 import defaultExport from './module.js'; // 混合导入 import defaultExport, { namedExport } from './module.js'; // 导入所有导出为命名空间对象 import * as moduleNamespace from './module.js'; // 仅执行模块,不导入任何内容 import './module.js';
实际示例
下面是一个简单的实现,展示ES模块的实际使用:
html
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>ES模块语法示例</title> <style> body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; max-width: 800px; margin: 0 auto; padding: 20px; background-color: #f5f8fa; color: #333; } .container { background-color: white; border-radius: 8px; padding: 20px; box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1); } h1 { color: #2c3e50; border-bottom: 2px solid #eee; padding-bottom: 10px; } .code-block { background-color: #f8f9fa; border-left: 4px solid #3498db; padding: 15px; margin: 15px 0; overflow-x: auto; font-family: 'Consolas', 'Monaco', monospace; } .example { background-color: #e8f4fc; padding: 15px; border-radius: 6px; margin: 15px 0; } button { background-color: #3498db; color: white; border: none; padding: 10px 15px; border-radius: 4px; cursor: pointer; margin: 5px; } button:hover { background-color: #2980b9; } .output { margin-top: 15px; padding: 15px; background-color: #f9f9f9; border-radius: 4px; min-height: 50px; } </style> </head> <body> <div class="container"> <h1>ES模块语法详解</h1> <section> <h2>命名导出与导入</h2> <div class="code-block"> // mathUtils.js<br> export const PI = 3.14159;<br> export function square(x) { return x * x; }<br> export function cube(x) { return x * x * x; }<br><br> // 使用方式<br> import { PI, square, cube } from './mathUtils.js'; </div> <div class="example"> <h3>示例:计算数学运算</h3> <button οnclick="calculateSquare()">计算平方</button> <button οnclick="calculateCube()">计算立方</button> <div class="output" id="mathOutput"></div> </div> </section> <section> <h2>默认导出与导入</h2> <div class="code-block"> // logger.js<br> export default function(message) {<br> console.log(`[LOG]: ${message}`);<br> }<br><br> // 使用方式<br> import log from './logger.js';<br> log('Hello, modules!'); </div> <div class="example"> <h3>示例:记录日志</h3> <button οnclick="logMessage()">记录日志</button> <div class="output" id="logOutput"></div> </div> </section> <section> <h2>混合导出与导入</h2> <div class="code-block"> // utilities.js<br> export const version = '1.0.0';<br> export function helper() { /* ... */ }<br> export default function mainUtility() { /* ... */ }<br><br> // 使用方式<br> import mainUtil, { version, helper } from './utilities.js'; </div> </section> <section> <h2>命名空间导入</h2> <div class="code-block"> // 导入所有导出为命名空间对象<br> import * as math from './mathUtils.js';<br><br> // 使用方式<br> console.log(math.PI);<br> math.square(5); </div> <div class="example"> <h3>示例:使用命名空间</h3> <button οnclick="useNamespace()">使用命名空间计算</button> <div class="output" id="namespaceOutput"></div> </div> </section> </div> <script type="module"> // 导入模块功能 import { PI, square, cube } from './mathUtils.js'; import log from './logger.js'; import * as math from './mathUtils.js'; // 使函数在全局可用以便按钮调用 window.calculateSquare = function() { const value = 5; const result = square(value); document.getElementById('mathOutput').innerHTML = `square(${value}) = ${result}`; }; window.calculateCube = function() { const value = 4; const result = cube(value); document.getElementById('mathOutput').innerHTML = `cube(${value}) = ${result}`; }; window.logMessage = function() { const message = `当前时间: ${new Date().toLocaleTimeString()}`; log(message); document.getElementById('logOutput').innerHTML = `已记录日志: "${message}" - 查看控制台获取详细信息`; }; window.useNamespace = function() { const value = 7; const squared = math.square(value); const cubed = math.cube(value); document.getElementById('namespaceOutput').innerHTML = `使用命名空间计算:<br>${value}² = ${squared}<br>${value}³ = ${cubed}`; }; </script> </body> </html>
模块文件
需要创建以下模块文件与HTML文件放在同一目录:
mathUtils.js:
javascript
export const PI = 3.14159; export function square(x) { return x * x; } export function cube(x) { return x * x * x; }
logger.js:
javascript
export default function(message) { const timestamp = new Date().toISOString(); const logMessage = `[${timestamp}] LOG: ${message}`; console.log(logMessage); return logMessage; }
关键特性说明
严格模式:ES模块自动处于严格模式
静态结构:导入导出必须在顶层作用域,不能条件导入
单例模式:多次导入同一模块只会执行一次
实时绑定:导入的是值的引用,不是拷贝
支持循环依赖:但需要小心设计
浏览器支持
现代浏览器都支持ES模块,但需要注意:
使用
<script type="module">
标签文件路径需要完整(包括扩展名)
通过本地服务器运行(如Live Server),不能直接文件协议打开