Module的语法

1.简介

Module是ES6模块化思想,他 的设计思想是尽量的静态化,使得编译时就确定模块的依赖关系,以及输入和输出的变量。

ES6模块不是对象,而是通过export命令显式指定输出的代码,再通过import命令输入

import { stat,exists,readFile} from 'fs';

上面代码的实质是从fs模块加载3个方法,其他方法不会加载。这种加载称为编译时加载或者静态加载,效率比commonjs模块的加载方式高。

es模块的好处

(1).不再需要UMD模块格式了,将来服务器和浏览器都会支持ES6模块格式,目前,通过各种工具库,已经做到了这一点

(2).将来浏览器的新API就能用模块格式提供,不再需要做成全局变量或者navigator对象的属性

(3).不再需要对象作为命名空间,未来这些功能可以通过模块提供。

2.严格模式

ES6的模块自动采用严格模式,不管你有没有在头部加“use strict”

严格模式限制

(1)变量必须先声明或使用

(2)函数的参数不能有同名属性

(3)不能使用with语句

(4)不能对只读属性赋值

(5)不能删除不可删除的属性

(6)禁止使用this指向全局对象

(7)增加了保留字(protected,static,interface)

3.export命令

模块的功能主要由两个命令构成:export和import

export命令用于规定模块对外的接口,import用于输入其他模块提供的功能

任何一个模块都是独立的文件,外界无法获取内部定义的变量或方法,必须通过export关键字输入该变量或者方法

例如:

export var firstName = "michael";
exprot var year = "2018";

或者用对象的方式输出:

var firstName = "michael";
var year = 2018;
export {firstName,year};

export命令可以输出函数或者类

export function multiply(x,y){
  return x*y;
}

用as关键字重命名

function a(){...}
function b(){...}

export {
  a as newNameA,
  b as newNameB, 
b as newNameB2//此处b可以用不同的名字输出两次
}

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

export var foo = "bar";
setTimeout(() => foo = "baz",500);

上面代码输出变量foo,值为bar,500毫秒后变成baz,这与commonjs不同,commonjs模块输出的值是缓存

export命令可以出现在模块最外层作用域的任何地方

4.import命令

使用export命令定义了模块的对外接口之后,其他js文件就可以通过import命令加载这个模块

//main.js
import {firstName,lastName,year} from "./profile.js";

function setName(element){
  element.textContent = firstName + '' + lastName;
}

import 也可以为引入的变量重新去名字,使用as关键字,同export相同

import命令输入的变量都是只读的,不可更改,如果为对象,改写属性是可以的,建议不要轻易改写

由于import是静态执行,即编译前执行,所以不能使用表达式和变量,这些只有在运行时才能得到结果的语法结构

5.模块的整体加载

//circle.js

export function area(radius){
  return Math.PI * radius * radius
}

export function circumference(radius){
  return 2 * Math.PI *radius;
}

正常加载模块:

//main.js

import {area,circumference} from './circle';

console.log("圆面积" + area(5));

整体加载模块:

import * as circle from './circle';

console.log('圆面积'+circle.area(5));

注意:整体加载的对象circle是静态分析,不允许运行时改变

6.export default命令

使用import命令的时候,用户需要知道所要加载的变量名或函数名,否则无法加载,export default 命令为模块指定默认输出;

export default function () {
  console.log("default");
}//默认输出一个函数

其他模块加载该模块时,import命令可以为该匿名函数指定任意名字

import customName from './sdfasdf';//不用使用大括号
customName();

export default也可以输出非匿名函数,但被视为匿名函数,引入时也可以任意命名

export default命令用于指定模块的默认输出,因此只能用一次,export default命令的本质是将后面的值赋值给default变量

7.export和import的复合写法

如果在一个模块中,先输入后输出同一个模块,import语句可以与export语句写在一起

export { foo, bar} from 'my_module';

//等同于
import { foo, bar} from 'my_module';
export { foo, bar}

需要注意的是,写成一行以后,foo和bar实际上并没有被导入当前模块,只是相当于对外转发的这两个接口,导致当前模块不能直接使用foo和bar

8.模块的继承

9.跨模块常亮

设置跨模块常量或者说一个值要被多个模块共享,可以采用下面的写法

//constants.js 模块
export const A = 1;
export const B = 2;
export const C = 3;

//test1.js 模块
import * as constants from './constants';
console.log(constants.A);//1
console.log(constants.B);//2

//test2.js模块
import {A,B} from './constants';
console.log(A);//1
console.log(B);//2

但是如果使用的变量非常多,可以建一个专门的constants目录,将各种常量写在不同的文件里面,保存在该目录下

//constants/db.js
export const db = {
  url:"",
  admin_username:"admin",
  admin_password:"admin password"
};

//constants/user.js
export const users = ['root', 'admin','staff']

将这些文件输出的常量,合并在index.js里面

//constants/index.js
export {db} from './db';
export {users} from './users';

使用的时候,直接加载index.js即可

//script.js
import {db,users} from './index'

10.import()

import会被javascript引擎静态解析,先于模块其他语句执行,所以不能用在语句中,必须放在顶层作用域中,虽然这样效率较高,但是无法在运行时加载,语法上,条件加载就不可以实现,因此引入import()函数,完成动态加载

import(aaa);其中参数aaa,指要加载的模块的位置

import()返回一个Promise对象

const main  = document.querySelector("main");
import('./section-module')
  .then(module => {
    module.loadPageInfo(main);
})
  .catch(err => {
    main.textContent = err.message;
})

适用场合

(1)按需加载

import()可以在需要的时候,再加载某个模块

button.addEventListener('click',event => {
  import('./dialogBox.js')
    .then(dialogBox => {
      dialogBox.open();
    })
    .catch(error => {
      
    })
})

监听事件,用户点击才会加载这个模块

(2)条件加载

import()放在if代码块,根据情况加载不同的模块

if(condition){
  import('moduleA').then(...)
}else{
  import('moduleB').then(...)
}

(3)动态模块路径

import(f()).then(...)根据函数f()返回的结果,加载不同的模块

 
  

你可能感兴趣的:(Module的语法)