前端架构系列

ESModule

2020-07-26  本文已影响0人  羽晞yose

模块化解决的问题

命名冲突(命名空间来解决)
采用自执行函数的方式 (解决代码的高内聚 低耦合问题)

模块的几种规范

esModule特点

  1. 可以变量提升,可以在未定义之前使用
console.log(a);

import {a} from './a.js';
  1. 不能放到作用域下,只能放到顶层环境
{
    import {a} from './a.js'; // 报错
}
  1. 导出的是变量,不是具体的值
// 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
})
  1. 默认导出 default,直接导出某个变量,外层引入的时候,可以直接获取到,并且default导出的是值
// default在导入的时候可以更改为其他变量名
// a.js
export default {a: 1, b: 2}

// index.js
import obj from './a.js';
  1. 导入并导出,但是不能使用导入的变量,如果导出的变量同名,以第一次导出的为准
// index.js
// 没有import关键字,直接export出去,这种做法是用于总入口,比如有个global.js,里面需要拿到a和b的导出变量
export * from './a.js';
export * from './b.js';

// global.js
import {a, b} from './index.js'
  1. 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 的区别就是,一个导出的是变量,一个导出的是值
  1. 动态导入,导入的结果会被包装成一个promise
let btn = document.createdElement('btn');

btn.addEventListener('click', () => {
    import('./a.js').then(res => {
        console.log(res.default)
    })
});

document.body.appendChild(btn);
上一篇 下一篇

猜你喜欢

热点阅读