Module

模块功能主要由两个命令构成:export和import。export命令用于暴露模块的对外接口,import命令用于引入其余模块提供的接口。函数

export命令

一个模块就是一个独立的文件。该文件内部的全部变量,外部没法获取。要想外部可以读取该模块内的变量,必须使用export关键字输出该变量。以下代码:code

// profile.js
export var firstName = 'Michael';
export var lastName = 'Jackson';
export var year = 1958;

也能够采用下面的写法:对象

// profile.js
var firstName = 'Michael';
var lastName = 'Jackson';
var year = 1958;

export {firstName, lastName, year};

export除了输出变量还能够输出函数或类(Class)。接口

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

注意:export命令规定的是对外接口,必须与模块内部的变量创建一一对应的关系。也就是说export的对象可使变量,函数或类,但不能是值。ip

// 报错
export 1;

// 报错
var m = 1;
export m;

正确的写法以下:element

// 写法一
export var m = 1;

// 写法二
var m = 1;
export {m};

import命令

export暴露接口,其余JS文件可使用import命令加载该模块,引入这个接口。io

// profile.js
export var firstName = 'Michael';
export var lastName = 'Jackson';
export var year = 1958;
// main.js
import {firstName, lastName, year} from './profile';

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

上面的import命令用于加载profile.js,import后面的大括号是定要从profile.js导入的变量名。大括号里面的变量必须必须与被导入模块(profile.js)对外接口的名称相同。
import后面的from指定模块文件的位置,能够是相对路径,也能够是绝对路径,.js后缀能够省略。若是只是模块名,不带有路径,那么必须有配置文件,告诉 JavaScript 引擎该模块的位置。console

import {myMethod} from 'util';

上面代码中,util是模块文件名,因为不带有路径,必须经过配置,告诉引擎怎么取到这个模块。编译

import命令是编译阶段执行的,在代码运行以前。
import命令具备提高效果,会提高到整个模块的头部,首先执行。因此以下代码不会报错。ast

foo();

import { foo } from 'my_module';

因为import是静态执行,因此不能使用只有在运行时才能获得结果的语法结构。

// 报错
import { 'f' + 'oo' } from 'my_module';

// 报错
let module = 'my_module';
import { foo } from module;

// 报错
if (x === 1) {
  import { foo } from 'module1';
} else {
  import { foo } from 'module2';
}

上面三种写法都会报错,由于它们用到了表达式、变量和if结构。在静态分析阶段,这些语法都是无法获得值的。

最后,import语句会执行所加载的模块,所以能够有下面的写法。

import 'lodash';

export default 命令

export default命令,为模块指定默认输出。

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

上面代码是一个模块文件export-default.js,它的默认输出是一个函数。
其余模块加载该模块时,import命令能够为该匿名函数指定任意名字。

// import-default.js
import customName from './export-default';
customName();   // 'foo'

export default命令用在非匿名函数前,也是能够的。

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

// 或者写成

function foo() {
  console.log('foo');
}

export default foo;

上面代码中,foo函数的函数名foo,在模块外部是无效的。加载的时候,视同匿名函数加载。
注意:下面比较一下默认输出和正常输出。

// 第一组
export default function crc32() { // 输出
  // ...
}
import crc32 from 'crc32'; // 输入

// 第二组
export function crc32() { // 输出
  // ...
};
import {crc32} from 'crc32'; // 输入

上面代码的两组写法,第一组是使用export default时,对应的import语句不须要使用大括号;第二组是不使用export default时,对应的import语句须要使用大括号。
export default命令用于指定模块的默认输出。显然,一个模块只能有一个默认输出,所以export default命令只能使用一次。因此,import命令后面才不用加大括号,由于只可能对应一个方法。

module.exports

Node 采用 CommonJS模块格式,在Node环境中,使用import命令加载 CommonJS模块,Node会自动将module.exports属性,看成模块的默认输出,即等同于export default。

// a.js
module.exports = {
  foo: 'hello',
  bar: 'world'
};

// 等同于
export default {
  foo: 'hello',
  bar: 'world'
};

import命令加载上面的模块,module.exports会被视为默认输出。

import baz from './a';
// baz = {foo: 'hello', bar: 'world'};
相关文章
相关标签/搜索