微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

ES6 VS Node && import VS require

Node: module.exports require

Node应用由模块组成,采用Commonjs模块规范。根据这个规范,每个文件就是一个模块,有自己的作用域。在这文件里面定义的变量、函数、类,都是私有的,对外不可见,因此规避掉了作用域污染。
根据Commonjs规定,每个模块内部,module变量代表当前模块,这个变量是一个对象,它的exports属性(即module.exports)是对外的接口。加载某个模块,其实就是加载该模块的exports属性

举例:

let a = "just a string"
let b = function(){
  console.log("just another string")
}
module.exports.a = a;
module.exports.b = b;

require:用于加载模块

var all = require("a.js");

console.log(all.a) // just a string
all.b() // just another string

exports 与 module.exports

为了方便,node为每个模块提供了一个exports变量,指向module.exports。这等同于在每个模块头部,有这么一行代码

var exports = module.exports

我们可以直接在exports对象上添加方法(等同于在 module.exports 添加一样)

let a = "just a string"
let b = function(){
  console.log("just another string")
}
exports.a = a;
exports.b = b;

P.S.不能直接将exports指向一个值,这会切断 exports 与 module.exports 的联系(但是可以用module.exports来指向一个值)

ES6: export import

export导出的模块,需要用import引入,而不能用require。
export命令规定的是对外的接口,必须与模块内部的变量建立对应关系。


const a = 'just a string';
// 有三种方法可以导出

// 第一种
export var b = a;
// 引用:
import { b } from "a.js"

// 第二种
export { a } 
// 引用:
import { a } from "a.js"

// 第三种
export { a as b }
// 引用:
import { b } from "a.js"
// 引用的时候也可以指定别名如:
import { b as c } from "a.js"

export 和 export default

1.export 和export default 均可用于导出(常量 | 函数 | 文件 | 模块)等。
2.可以在其他文件中通过 import+(常量 | 函数 | 文件 | 模块)名的方式,将其导入,以便能够进行使用。
3.在一个文件或者模块中,export、import 可以有多个,但 export default 仅有一个

const a = 'just a string'
const b = 'another string'

export { a }
export { b }
// 引用

4.通过 export 方式导出,在导入时要用花括号{ };而通过 export default 方式导出的,则不需要:

const a = 'just a string'
export default a
// 引入
import a from "a.js"

import *

一个js文件中定义的方法,模块,对象等,全部导出,一般结合别名使用,如:

const a = 'just a string'
const b = 'another string'
export { a }
export { b }
// 引入
import * as all from "a.js"
all.a
all.b

如果用export default导出,然后用import * 引入

const a = 'just a string'
export default a
// 引入
import * as all from "a.js"
all.default.a

##补充
1.本质上,export default就是输出一个叫做default的变量或方法,然后系统允许你为它取任意名字。所以,下面的写法是有效的。

import { default as all } from "a.js"
all.a

正是因为export default命令其实只是输出一个叫做default的变量,所以它后面不能跟变量声明语句

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

// a.js
export let a = 'just a string';
setTimeout(() => a= 'change to another string', 500);

// main.js
import { a } from "a.js"
console.log(a);   // just a string 
setTimeout(()=> console.log(a),2000)
console.log(a);  // change to another string

这一点与 Commonjs 规范完全不同。Commonjs 模块输出的是值的缓存,不存在动态更新.

3. export 和 import 命令可以出现在模块的任何位置,只要处于模块顶层就可以。如果处于块级作用域内,就会报错,这是因为处于条件代码块之中,就没法做静态优化了,违背了 ES6 模块的设计初衷。

4. import命令输入的变量都是只读的,因为它的本质是输入接口。也就是说,不允许在加载模块的脚本里面,改写接口。

5. import命令具有提升效果,会提升到整个模块的头部,首先执行。

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

7. import语句会执行所加载的模块,因此可以有下面的写法。

8. 目前阶段,通过 Babel 转码,Commonjs 模块的require命令和 ES6 模块的import命令,可以写在同一个模块里面,但是最好不要这样做。因为import在静态解析阶段执行,所以它是一个模块之中最早执行的。

9. 如果想在一条import语句中,同时输入方法和其他接口,可以写成下面这样。

import _, { each, forEach } from 'lodash';

10. export default也可以用来输出类。

// MyClass.js
export default class { ... }

// main.js
import MyClass from 'MyClass';
let o = new MyClass();

11. export 与 import 的复合写法

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

export { a, b } from "a.js"

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐