JavaScript中AMD和ES6模块的导入导出对比

17次阅读

共计 5169 个字符,预计需要花费 13 分钟才能阅读完成。

我们前端在开发过程中经常会遇到导入导出功能,在导入时,有时候是 require,有时候是 import 在导出时,有时候是 exports,module.exports,有时候是 export,export default 今天我们对这些内容进行简单的介绍
import,export,export default
import,export,export default 属于 ES6 规范
import
import 是在编译过程中执行也就是说是在代码执行前执行,比如说,import 后面的路径写错了,在运行代码前就会抛错,在编写代码时,import 不是一定要写在 js 的最前面 import 命令具有提升效果,会提升到整个模块的头部,首先执行。(是在编译阶段执行的)import 是静态执行的因为 import 是静态执行的,不能使用表达式和变量,即在运行时才能拿到结果的语法结构比如,不能再 if 和 else 中使用 import 再比如,import 后的 from 的路径,可以是相对路径,可以是绝对路径,但是不能是根据变量得来的路径
//import 路径不可以为变量
var url = ‘./output’
import {
a,
b
} from url// 这么写会报错
//——————
//import 的引入与否不能和代码逻辑向关联
let status= true
if(status){
import {
a,
b
} from url// 这么写会报错
}
import 可以使用 as 进行重命名 import 的有很多种导入方式,
import foo from ‘./output’
import {b as B} from ‘./output’
import * as OBj from ‘./output’
import {a} from ‘./output’
import {b as BB} from ‘./output’
import c, {d} from ‘./output’
导入的方式和导出有些关联,我们在下面说导出的时候,对以上这些导入方式进行逐一介绍
exoprt 和 export default
将 exoprt 和 export default 放在一起,因为它们关联性很大简单说:export 是导出,export default 是默认导出一个模块可以有多个 export,但是只能有一个 export default,export default 可以和多个 export 共存 export default 为默认导出,导出的是用 {} 包裹的一个对象,以键值对的形式存在导出的方式不同,导入的方式也就不同,所以建议同一个项目下使用同一的导入导出方式,方便开发 export default 解构以后就是 export 通过两个直观的 demo 看下 export 和 export default 的区别先看一段代码(export)output.js
const a = ‘valueA1’
export {a}
input.js
import {a} from ‘./output.js’// 此处的 import {a}和 export {a},两个 a 是一一对应关系
console.log(a)//=>valueA1
留意上面的代码其中 export {a}导出的 a,和 import {a}导入的 a 是同一个 a 再看一段代码(export default)
const a = ‘valueA1’
export default{a}
input.js
import a from ‘./output.js’// 此处的 a 和 export default{a},不是一个 a,
console.log(a)//=>{a: ‘valueA1’}
看下 export default 的栗子中的 input.js,我们稍作改动
import abc from ‘./output.js’// 此处的 a 和 export default{a},不是一个 a,
console.log(abc)//=>{a: ‘valueA1’}
我们做了些改动,但是输出没有变化,import 导入的是 export default 下的对象,叫什么名字都可以,因为只会存在一个 export default
exoprt 和 export default 混合使用
exoprt 和 export default 在同一个模块中同时使用,是支持的,虽然我们一般不会这么做看一个栗子 output.js
const a = ‘valueA1’
const b = ‘valueB1’
const c = ‘valueC1’
const d = ‘valueD1’
function foo() {
console.log(`foo 执行,c 的值是 ${c}`);
}
export {a}
export {b}
export default {b,d,foo}
input.js
import obj, {a,b} from ‘./output’
console.log(a); //=>valueA1
console.log(b); //=>valueB1
console.log(obj); //=>{b: ‘valueB1’, d: ‘valueD1’, foo: [Function: foo] }
as 重命名
通过 exoprt 和 export default 导出的在 import 引入时都支持通过 as 进行重命名看个栗子还是上面的那个 output.js
const a = ‘valueA1’
const b = ‘valueB1’
const c = ‘valueC1’
const d = ‘valueD1’
function foo() {
console.log(`foo 执行,c 的值是 ${c}`);
}
export {a}
export {b}
export default {b,d,foo}
input.js
import {a as A} from ‘./output’
import {* as A} from ‘./output’// 这是不支持的
import * as obj from ‘./output’
console.log(A); //=>valueA1
console.log(obj); //=>{a: ‘valueA1’,default: { b: ‘valueB1’, d: ‘valueD1’, foo: [Function: foo] },b: ‘valueB1’ }
as 后面的变量是你要在 input.js 中使用的重点看这一部分
import {* as A} from ‘./output’// 这是不支持的
import * as obj from ‘./output’
console.log(obj); //=>{a: ‘valueA1’,default: { b: ‘valueB1’, d: ‘valueD1’, foo: [Function: foo] },b: ‘valueB1’ }
代表了所有,包括了 export 和 export default 导出的
我们之前说 import{}和 export{}, 是一一对应关系,所以在 export 导出的,在 import{}不支持使用 * 关于 import,export,export default 先介绍到这里,我们继续
require,exports,module.exports(记得后面的 s)
这是 AMD 规范
require
require 是运行时调用,所以 require 理论上可以运用在代码的任何地方
require 支持动态引入
例如,这样是支持的
let flag = true
if (flag) {
const a = require(‘./output.js’)
console.log(a); // 支持
}
require 路径支持变量
let flag = true
let url = ‘./output.js’
if (flag) {
const a = require(url)
console.log(a); // 支持
}
通过 require 引入,是一个赋值的过程
exports 与 module.exports
根据 AMD 规范每个文件就是一个模块,有自己的作用域。在一个文件里面定义的变量、函数、类,都是私有的,对其他文件不可见。每个模块内部,module 变量代表当前模块。这个变量是一个对象,它的 exports 属性(即 module.exports)是对外的接口。加载某个模块,其实是加载该模块的 module.exports 属性。
为了方便,Node 为每个模块提供一个 exports 变量,指向 module.exports。这等同在每个模块头部,有一行这样的命令。
const exports = module.exports;
所以说以下两种写法等价
exports.a =’valueA1′
module.exports.a=’valueA1′
前面说在每个模块提供一个 exports 变量,指向 module.exports。所以不能直接给 exports 赋值,赋值会覆盖
const exports = module.exports;
直接给 exports 赋值会切断 exports 和 module.exports 的关联关系看一个栗子 output.js
const a = ‘valueA1’
const b = ‘valueB1’
const c = ‘valueC1’
module.exports = {c}
exports.b = b// 当直接给 module.exports 时,exports 会失效
module.exports.a = a
input.js
const obj = require(‘./output.js’)
console.log(obj); //=>{c: ‘valueC1’, a: ‘valueA1’}
继续看代码 output.js
// 部分省略
exports.b = b// 这样可以生效
module.exports.a = a
input.js
const obj = require(‘./output.js’)
console.log(obj); //=>{b: ‘valueB1’, a: ‘valueA1’}
再看一段代码 output.js
// 部分省略
module.exports = {c}
module.exports.a = a
input.js
const obj = require(‘./output.js’)
console.log(obj); //=>{c: ‘valueC1’, a: ‘valueA1’}
当直接给 module.exports 时,exports 会失效
交叉使用
在 ES6 中 exprod default 导出的是一个对象在 AMD 中 exports 和 module.exports 导出的也都是一个对象所以如果你手中的项目代码支持两种规范,那么事可以交叉使用的(当然不建议这么去做)通过 export 导出的不一定是一个对象
demo1
output.js
// 部分省略
module.exports = {c}
module.exports.a = a
inputj.s
import obj from ‘./output’
import {a} from ‘./output’
console.log(a);//=>valueA1
console.log(obj);//=>{c: ‘valueC1’, a: ‘valueA1’}
demo2
output.js
const a = ‘valueA1’
const b = ‘valueB1’
const c = ‘valueC1’
function foo() {
console.log(`foo 执行,c 的值是 ${c}`);
}
export {a}
export default {b,c,foo}
export {b}
input.js
const a = require(‘./output.js’)
console.log(a); //=>{a: ‘valueA1’,default: { b: ‘valueB1’, c: ‘valueC1’, foo: [Function: foo] }, b: ‘valueB1’ }
总结

require,exports,module.export 属于 AMD 规范,import,export,export default 属于 ES6 规范
require 支持动态导入,动态匹配路径,import 对这两者都不支持
require 是运行时调用,import 是编译时调用
require 是赋值过程,import 是解构过程
对于 export 和 export default 不同的使用方式,import 就要采取不同的引用方式,主要区别在于是否存在{},export 导出的,import 导入需要{}, 导入和导出一一对应,export default 默认导出的,import 导入不需要{}
exports 是 module.export 一种简写形式,不能直接给 exports 赋值
当直接给 module.export 赋值时,exports 会失效

更多前端资源请关注微信公众号“前端陌上寒”
原文链接
参考链接关于 import 与 require 的区别 JS 中的 require 和 import 区别 module.exports 和 exports 和 export 和 export default 的区别,import 和 require 的区别

正文完
 0