ES6-Module

前言

许多年前,我们引入代码,是直接用 script src引入, 或者自己写一个 loadScript。

用script src方式的话,当项目中js文件多了,页面上会有很多script标签,抛开性能暂且不说,本身代码就非常丑陋,而且很不好维护,尤其是当 js 文件有依赖关系时,更加难以处理。

为了解决这一痛点,处理好 js 的加载和依赖关系,并推进 js 模块化开发, 于是就有了 用于浏览器端的 CMD, AMD 等规范,  用于服务端(比如nodejs)的 CommonJs规范, 以及最终的标准 ES6 Module 规范。先大致了解一下这几个东东。

CMD: Common Module Definition - 公共模块定义,  是玉伯先生的SeaJS 在推广过程中对模块定义的规范化产出。

AMD:Asynchromous Module Definition - 异步模块定义  是RequireJS在推广过程中对模块定义的规范化产出。

CommonJs规范:服务端规范,文件即模块。用 module.exports 导出模块,require 引入文件/模块。

ES6 Module:ES6 模块标准。

 

语法以及运用

CMD、 AMD 、CommonJs不作过多描述。想了解的童鞋请上网搜索。这里主要记录 ES6 Module。 

 

ES6 Module 自动采用严格模式,不管你有木有在代码中加上 'use strict'。

export 导出变量, import 导入变量。搞过后端语言的童鞋,应该很熟悉吧。

 

export 的用法

//export  可以导出 变量,对象, 函数,类。
export const root = 'linux'; let username = 'captain'; let password = 'pwd'; export { username, password } export const add = (x) => x + x; export class fun{}

注意一点, export 命令规定的是对外的接口,所以要保证接口名必须与模块内部变量建立一一对应的关系。

这句话是什么意思,就是不能定义好变量,就直接把变量 export。因为这时候,export 出去的其实是变量的值。

所以要么在定义时就 export, 要么在文件末尾 export 一个对象,对象里是要导出的变量,成键值对关系。

//报错
export 1;
//正确
const t = 1;
export {
    t
}

//报错
const test = () => {}
export test;
//正确
export test = () => {}
export {
    test  
}

有时候,我们想给导出的变量换个名字, 这个时候就可以用 as 关键字了。重命名后,一个变量可以导出多次。

语法为: 变量名  as  新变量名

const f1 = () => {}
const f2 = () => {} 

export {
   f1 as fun1,
   f2 as fun2,
  f2 as alsoFun2 }

最后: export语句输出的接口,与其对应的值是动态绑定关系,即通过该接口,可以取到模块内部实时的值。

 

import 的用法

使用 export 命令定义了模块的对外接口以后, 就可以用 import 加载这个模块了。同样的,import 也有 as 关键字, 也是用于重命名。

以下是 import 的常用语法

import { funName } from 'file.js';

import { funName as newFunName } from 'file.js';

import * as newModuleName from 'file.js';

//如果模块用的是 export default
import defaultName from 'file.js';

注意一点: import命令具有提升效果,会提升到整个模块的头部,首先执行。

 

export default 的用法

export default 用法模块的默认输出。一个模块只能有一个默认输出,因此 export default 命令只能使用一次。

本质上,export default 就是输出一个叫做default的变量或方法,然后系统允许你为它取任意名字。

因为 export default 命令的本质是将后面的值,赋给default变量,所以也可以直接 export default 一个变量。

这个和 export 有些区别,直接 export 一个变量是会报错的。

export default function () { console.log('export default'); }

export default function add() { return x + x }

注意一点: 正是因为export default命令其实只是输出一个叫做default的变量,所以它后面不能跟变量声明语句, 比如 var, let, const 等。

 

模块的继承

其实也就是 export 和 import 的复合写法。

注意一点:如果是直接将 继承 的方法 export 出去,当前模块是无法调用继承的方法的。这时候如果需要使用继承的方法,可以分开写,先 import 再 export。

//假如以及有一个 add 模块 
export const add = (x) => x + x;
export const add2 = (y) => y + y + y;

//现在我们需要新增一个 math 模块,继承add模块,并导出
export * from 'add.js';
export const mult = (x) => x * x;

//或者我们只需要继承 add 方法,不要 add2 方法。
export { add as addNewName } from 'add.js';
export const mult = (x) => x * x;

//以下是分开的写法
import { add } from 'add.js';
export add;
export const mult = (x) => x * x;

 

模块按需加载 

import( url ) 可以实现按需加载,或条件加载。 它返回一个 promise 对象。单页面应用在配置 route 时大都需要使用 import 按需加载。

 

总结:

export 命令规定的是对外的接口,所以要保证接口名必须与模块内部变量建立一一对应的关系。

export 不能直接导出一个变量或一个值, export default 可以。不过 export defult 后面不能有字面量声明语句, 而 export 可以。

模块可以继承。继承时, export * 命令会忽略模块的 default 方法。

 

posted @ 2018-04-29 20:38  jkCaptain  阅读(129)  评论(0编辑  收藏  举报