CommonJs 和 ES Module
CommonJs
1. 导出:
module.exports = {
name : "小明"
}
module.exports.name = "小明"
exports.name = "名字"
exports.sex = "male"
可以使用module.exports 导出,也可以只使用exports 导出,不同的是,使用多个exports导出时,只有最后一个导出会生效,上面的例子中只有sex导出成功。
2.导入
// index.js
module.exports.name = "小明"
let data = require("./index.js")
console.log(data) // { name: "小明" }
可以使用require来获取
动态导入
CommonJs支持动态导入
let list = ["./index.js", "./config.js"]
list.forEach((url) => require(url))
导入值的变化
// index.js
let num = 0;
module.exports = {
num,
add() {
++ num
},
numValue() {
console.log(num)
}
}
let { num, add,numValue } = require('./index.js')
console.log(num) // 0
add()
console.log(num) // 0
numValue() // 1
num = 10
console.log(num) // 10
在上述例子中可以看到,在调用add()方法之后,num的值并没有被改变,但是在调用numValue的时候发现num改变了,说明此时改变的是index.js中的num,接着我们对num进行赋值,num的值变成了10。
因此可以说明,通过CommonJs导入的基本变量是深拷贝的,复杂类型是属于浅拷贝
ES Module
1.导出
// 变量导出
export const name = "小明"
// 函数导出
export function fn1 () {}
export const fn2 = () => {}
// 多个一起导出
const name = "小明"
const sex = "male"
export {name, sex}
// 默认导出
export default = {
fn3() {},
msg: "Hello ES Module"
}
在ES Module中分为单个导出和默认导出,并且默认导出的优先级比单个导出要高,也就是说,当两种方法在导入的时候同时使用,需要先导入默认输出。
2. 导入
// index.js
export const name = "小明"
export const sex = "male"
import { name, sex } from "./index.js"
console.log(name, sex) // "小明", "male"
使用 import 语法导入,并且单个导入需要使用花括号 { }
导入值的变化
// index.js
export let num = 0;
export function add() {
++ num
}
import { num, add } from "./index.js"
console.log(num) // 0
add()
console.log(num) // 1
num = 10 // 抛出错误
在这里使用add()方法时,num的值发生了变化,在直接修改num的值的时候,发生了错误。说明ES Module导出的值是只读的。
import的变量是只读的,不论是基本数据类型还是复杂数据类型。当模块遇到import命令时,就会生成一个只读引用。等到脚本真正执行时,再根据这个只读引用,到被加载的那个模块里面去取值。
对于动态来说,原始值发生变化,import加载的值也会发生变化。不论是基本数据类型还是复杂数据类型。
静态
就是Es Module语句import只能声明在该文件的最顶部,不能动态加载语句,Es Module语句运行在代码编译时。
总结
CommonJS
- 可以动态加载,代码发生在运行时
- 导出的值是拷贝的,基本变量是深拷贝的,复杂类型是属于浅拷贝
ES Module
- 不可以动态加载,属于静态,需要在文件最顶部声明,代码发生在编译时
- 可以单个导出,也可以默认导出
- 导出的值是只读的,不能修改