一、CommonJS介绍
导入:require
输出:exports或module.exports
exports
每个模块上有一个独立对象exports,模块对外输出的API就绑定在这个对象上
var name = "lihegui"
var sex = "男"
var func2 = function() {
console.log("func2");
};
exports.name = name;
exports.sex = sex;
exports.function2 = func2;
exports.people = {
name,
sex
}
var Math=require('math');
上面例子中require的参数仅仅是模块名字的字符串,没有带有路径,引用的是a.js所在当前目录下的node_modules目录下的math模块。如果当前目录没有node_modules目录或者node_modules目录里面没有安装math模块,便会报错。
如果要引入的模块在其他路径,就需要使用到相对路径或者绝对路径,例如:
const {name,sex,people} = require("./function.js")
module
在每一个模块中,module对象代表该模块自身
它是对象。这个对象有一个id属性,表示该模块的id,同时应该是只读属性。
let name = "lihegui"
let sex = "男"
module.exports = {
name,
sex
}
exports和module的关系
exports是module对象内的一个空对象,如果先用exports输出,再用module.exports输出,则会导致module.exports覆盖exports,因此,应该避免混用二者。
二、ES6
导出:export
导入:import
特点
- ES6 的模块自动开启严格模式,不管你有没有在模块头部加上 use strict;
- 每一个模块内声明的变量都是局部变量,不会污染全局作用域
- 每一个模块只加载一次(是单例的), 若再去加载同目录下同文件,直接从内存中读取
export
// 导出变量,变量可以是任意类型
export const name = 'es module'
// 导出方法
export function foo() {}
// 导出类
export class Person{}
//导出多个变量,这里需要特别注意的是export { name, foo, Person }中的{ }并不是对
//象,他是export导出变量的一种语法
const name = 'es module'
function foo () {}
class Person {}
export { name, foo, Person }
as关键字
如果我们希望对导出的变量名称进行修改,则可以使用as关键字来进行修饰变量 as 别名,但这个方法只适用于export {}
const name = 'es module'
export { name as alias }
default关键字
顾名思义,default代表了一个默认导出的变量,export default可以导出任意的变量或者对象
const name = 'es module'
export default name
or
export default { name } // 这里的{},是一个对象
or
export {name as default} // 这样也可以默认导出name
import
使用import { } 导入的变量并不是将值拷贝一份,而是指向其变量的地址,所以模块内导出的值发生变化,导入时的变量也会发生变化,且该变量不可被修改(这里的修改是指重新赋值的意思)
对于普通导出的值
// 导出
let name = "lihegui",
sex = "男"
export {name,sex}
// 导入
import {name,sex} from "./xxx.js"
对于default导出的值
//导出
let name = "lihegui"
export defalut name
//导入
import people_name from "./xxx/js"
关键字
import {a, b, c, d, e} from './modules.js'
// or
import * as param from './modules.js'
console.log(param)
// { ... } param是一个包含所有成员的对象
import关键字不能省略./和后缀
import()用于Vue懒加载
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
const Home = () => import("@/components/Home");
export default new Router({
routes:[
{
path:'/';
name:'home',
component:Home
}
]
})
二、二者有什么区别
- CommonJS输出的是值的拷贝,原始类型的值被缓存,不随模块内部的改变而改变;
- 而ES6模块输出的是值的引用,并且是只读引用,不能修改值。当js引擎解析脚本时,遇到加载import,就会生成一个只读引用,当真正用到模块里边的值的时候,就会去模块内部去取;
- CommonJS 模块是运行时加载:会在运行时加载整个模块,生成一个对象,然后再在这个对象上读取方法;
- ES6 模块是编译时加载:ES6模块不是对象,而是通过export命令 显式指定输出的代码。在import时直接输入制定代码。这种加载称为“编译时加载”或者静态加载,即 ES6 可以在编译时就完成模块加载,效率要比 CommonJS 模块的加载方式高。