模块化解决的问题:
命名冲突(命名空间来解决)
采用自执行函数的方式 (解决代码的高内聚 低耦合问题)
模块的几种规范
cmd:例如seajs
amd:例如requirejs
commonjs模块规范 node采用的就是该规范
导入 -,导出:require module.export
es6模块规范 esModule es6原生支持的规范(目前需要使用babel来兼容)
导入 - import,导出 - export
umd 统一模块,支持多种规范混合使用
esModule特点:
- 可以变量提升,可以在未定义之前使用
console.log(a);
import {a} from './a.js';
- 不能放到作用域下,只能放到顶层环境
{
import {a} from './a.js'; // 报错
}
- 导出的是变量,不是具体的值
// a.js
let a = 1;
let b = 2;
let c = 3;
setInterval(() => {
a++
}, 1000);
export {
a,
b,
c
}
// index.js
import * as obj from './a.js'; // 将变量全部导出,取的时候通过obj.a,obj.b来取
setInterval(() => {
console.log(obj.a, obj.b, obj.c);
// 结果可以看到obj.a一直在变
// 假如取的是a的值,那么后面a.js中不管a再怎么变,这边取到的a还会一直是最初的1
})
- 默认导出 default,直接导出某个变量,外层引入的时候,可以直接获取到,并且default导出的是值
// default在导入的时候可以更改为其他变量名
// a.js
export default {a: 1, b: 2}
// index.js
import obj from './a.js';
- 导入并导出,但是不能使用导入的变量,如果导出的变量同名,以第一次导出的为准
// index.js
// 没有import关键字,直接export出去,这种做法是用于总入口,比如有个global.js,里面需要拿到a和b的导出变量
export * from './a.js';
export * from './b.js';
// global.js
import {a, b} from './index.js'
- defalut导出的是值,常见面试题:export 和 export default的区别
// a.js
let a = 100;
let q = 100;
export default q;
export {a};
setInterval(() => {
a++;
q++
})
// index.js
import obj, {a} from './a';
setInterval(() => {
console.log(obj, a);
})
// 可以看到a会变,而obj不会
// 因此 export 变量 和 export default 的区别就是,一个导出的是变量,一个导出的是值
- 动态导入,导入的结果会被包装成一个promise
let btn = document.createdElement('btn');
btn.addEventListener('click', () => {
import('./a.js').then(res => {
console.log(res.default)
})
});
document.body.appendChild(btn);
网友评论