0
点赞
收藏
分享

微信扫一扫

ES6模块

kmoon_b426 2022-04-21 阅读 40

ES6模块

CommonJS和AMD都是运行时加载。ES6在语言规格层面上实现了模块功能,是编译时加载,完全可以取代现有的CommonJS和AMD规范,可以成为浏览器和服务器通用的模块解决方案。

ES6模块使用——export

(1)导出一个变量

export var name = 'pengpeng';

(2)导出一个函数

export function foo(x, y){}

(3)常用导出方式(推荐)

// person.js
const name = 'dingman';
const age = '18';
const addr = '卡尔斯特森林';

export { firstName, lastName, year };

(4)As用法

const s = 1;
export {
  s as t,
  s as m, 
}

可以利用as将模块输出多次。

ES6模块使用——import

(1)一般用法

import { name, age } from './person.js';

(2)As用法

import { name as personName } from './person.js';

import命令具有提升效果,会提升到整个模块的头部,首先执行,如下也不会报错:

getName();

import { getName } from 'person_module';

(3)整体模块加载 *

//person.js
export name = 'xixi';
export age = 23;

//逐一加载
import { age, name } from './person.js';

//整体加载
import * as person from './person.js';
console.log(person.name);
console.log(person.age);

ES6模块使用——export default

区别

export命令对外输出了指定名字的变量(变量也可以是函数或类)。

与export default命令的区别:import命令接受一对大括号,里面指定要从其他模块导入的变量名。大括号里面的变量名,必须与被导入模块对外接口的名称相同。

如果想为输入的变量重新取一个名字,import命令要使用as关键字,将输入的变量重命名。

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

使用import命令的时候,用户需要知道所要加载的变量名或函数名,否则无法加载。但是,用户肯定希望快速上手,未必愿意阅读文档,去了解模块有哪些属性和方法。

为了给用户提供方便,让他们不用阅读文档就能加载模块,就要用到export default命令,为模块指定默认输出。因此export default命令只能使用一次。所以,import命令后面才不用加大括号,因为只可能唯一对应export default命令。

其实export default,在项目里用的非常多,一般一个Vue组件或者React组件我们都是使用export default命令,需要注意的是使用export default命令时,import是不需要加{}的。而不使用export default时,import是必须加{},示例如下:

//person.js
export function getName() {
 ...
}
//my_module
import {getName} from './person.js';

-----------------对比---------------------

//person.js
export default function getName(){
 ...
}
//my_module
import getName from './person.js';

export default其实是导出一个叫做default的变量,所以其后面不能跟变量声明语句。

//错误
export default var a = 1;

值得注意的是我们可以同时使用export 和export default

//person.js
export name = 'dingman';
export default function getName(){
  ...
}

//my_module
import getName, { name } from './person.js';

前面一直提到,CommonJS是运行时加载,ES6时编译时加载,那么两个有什么本质的区别呢?

ES6模块与CommonJS模块加载区别

ES6模块的设计思想,是尽量的静态化,使得编译时就能确定模块的依赖关系,以及输入和输出的变量。所以说ES6是编译时加载,不同于CommonJS的运行时加载(实际加载的是一整个对象),ES6模块不是对象,而是通过export命令显式指定输出的代码,输入时也采用静态命令的形式:

//ES6模块
import { basename, dirname, parse } from 'path';

//CommonJS模块
let { basename, dirname, parse } = require('path');

以上这种写法与CommonJS的模块加载有什么不同?

  • 当require path模块时,其实 CommonJS会将path模块运行一遍,并返回一个对象,并将这个对象缓存起来,这个对象包含path这个模块的所有API。以后无论多少次加载这个模块都是取这个缓存的值,也就是第一次运行的结果,除非手动清除。
  • ES6会从path模块只加载3个方法,其他不会加载,这就是编译时加载。ES6可以在编译时就完成模块加载,当ES6遇到import时,不会像CommonJS一样去执行模块,而是生成一个动态的只读引用,当真正需要的时候再到模块里去取值,所以ES6模块是动态引用,并且不会缓存值。

因为CommonJS模块输出的是值的拷贝,所以当模块内值变化时,不会影响到输出的值。基于Node做以下尝试:

//person.js
var age = 18;
module.exports ={
  age: age,
  addAge: function () {
    age++;
  }
} 

//my_module
var person = require('./person.js');
console.log(person.age);
person.addAge();
console.log(person.age);

//输出结果
18
18

可以看到内部age的变化并不会影响person.age的值,这是因为person.age的值始终是第一次运行时的结果的拷贝。

再看ES6

//person.js
export let age = 18;
export function addAge(){
  age++;
}

//my_module
import { age, addAge } from './person.js';
console.log(age);
addAge();
console.log(age);

//输出结果
18
19
举报

相关推荐

[ES6]模块

ES6 模块简介

ES6的 模块

ES6模块化

Node与ES6模块

ES6中module模块

0 条评论