随着前端应用日益复杂,代码量逐渐增大,对于代码的组织和管理造成了一定的困扰。在ES6中,提供了完善的模块化语法,可以更好地解决代码复杂性问题。本文将就ES6中的模块化语法及其使用技巧进行介绍。
模块化介绍
在ES6之前,前端开发中广泛使用<script>标签来实现代码的引入和管理。这种方式存在一定的缺陷,代码之间的关系不够清晰,不易于管理和维护。而ES6提供了模块化语法,可以将可以将程序中的代码按一定规则拆分成独立的模块,每个模块仅包含自己特有的变量、函数和对象等。可以更好地解决代码复杂性问题,比如避免全局变量污染和循环依赖等问题。
ES6模块化语法,一共有两种语法:导入和导出。模块导出export和模块导入import。
导出模块
在模块定义文件中,我们需使用 export 关键字定义模块,除了 default export 只能 export 一次外,其他 export 可以 export 多次。
- 导出可单独导出的变量、函数
// 单独导出变量
export const PI = 3.14;
// 单独导出函数
export function sum(a, b) {
return a + b;
}- 导出可单独导出的类
// www.javascriptcn.com code example
// 单独导出类
export class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
sayHi() {
console.log(`hi, my name is ${this.name}, i am ${this.age} years old!`);
}
}- 导出 默认情况下只是能导出一个默认值,不需要加括号
// 默认导出
export default function sayHello(name) {
console.log(`hello, ${name}!`);
}导入模块
强烈建议按以下方式使用 ES6 的模块:
- 使用
import来引入模块,记得要加上{},导入模块名不用添加文件后缀,如.js。
// 导入单个模块
import { PI, sum } from './math';
// 导入整个模块,用*号代表所有组件; 可以导入所有的export default 和export写的内容
import * as math from './math';
// 导入用default导出的变量、函数
import sayHello from './utils';
// 导入用default导出的类
import Person from './Person';模块化使用技巧
模块优先
在开发过程中,我们必须尽可能多的使用 模块,它可以让我们的代码 更简单、更易维护,以及 容易引入 其他代码库 的指定部分。同时,模块是作为 ES6 对 JavaScript 开放性的重要改进之一,JavaScript 开发者都应该尝试按照 ES6 标准编写应用代码,即充分应用模块化思想。
模块中的默认导出
我们可以使用export default语法来导出一个默认值,与其他导出的值不同,可以在一个模块中只有一次。导入默认值时,不需要在import语句中指定导出名。
例:
// 在模块中默认导出一个函数
export default function sayHello(name) {
console.log(`Hello, ${name}!`);
}
// 导入默认输出
import sayHello from './hello';
// 使用
sayHello("world"); // Hello, world!模块中的命名导出
在模块中定义的变量和函数必须作为导出值才能从模块外部使用,我们可以使用语法export {name}来命名导出单独的模块值。命名导出允许在其他模块中命名引用它们。
例:
// www.javascriptcn.com code example
// 导出样式1
export function add(a, b) {
return a + b;
};
// 导出样式2
function sub(a, b) {
return a + b;
};
function mul(a, b) {
return a * b;
};
export { sub, mul };
// 导入
import { add } from './calc';
import { sub, mul } from './calc';分离 dependencies 和 devDependencies
由于部分工程只会在本地开发,而 JS 的浏览器或者 node 环境上执行的环境差异很大,所以我们可以将 devDependencies 和 dependencies 分离,缩小项目依赖范围。
举个例子:在 prod 中,我们不需要测试框架,如果都不分离而只是安装在 dependencies 中,就会导致额外的安装和非必要的引入。
在制作 component 的时候更是如此,这则会促使逐渐适应 TypeScript 来实现更严谨的工作流。
保证数据不变
最好保证导入的变量或对象不可改变,比如将对象赋值给一个新变量,这样可以确保在不意识到的情况下不修改了其他代码或者其他地方的变量的引用。
例:
// www.javascriptcn.com code example
// module1.js
export const thing1 = { id: "thing1" };
export const thing2 = { id: "thing2" };
// module2.js 引用 module1.js 的变量
import { thing1, thing2 } from "./module1";
export let foo = [thing1, thing2];
// 这种情况下,改变 foo 中的 thing1 会影响 module1 中的 thing1。
// 我们最好使用 Object.freeze() 来确保这不会发生,经过Object.freeze之后,内部的对象不可修改
import { thing1, thing2 } from "./module1";
export let foo = Object.freeze([thing1, thing2]);
// foo 将永远是一个包含 thing1 和 thing2 的非变更的数组。结语
ES6中的模块化语法为前端开发提供了强大的工具,有效地解决了代码的复杂性问题。但是在使用的过程中,我们也需要注意各种问题,比如模块优先、默认导出和命名导出、分离dependencies和devDependencies、保证数据不变等等问题。只有在实际开发中不断实践探索,才能更好地理解并使用ES6模块化语法。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67cffbcce46428fe9ec608c8