JavaScript 模块化 —— 从概念到原理

走过路过发现 bug 请指出,拯救一个辣鸡(但很帅)的少年就靠您啦!!!

1. 为什么需要 Javascipt 模块化?

1.解决命名冲突。将所有变量都挂载在到全局 global 会引用命名冲突的问题。模块化可以把变量封装在模块内部。
2.解决依赖管理。Javascipt 文件如果存在相互依赖的情况就需要保证被依赖的文件先被加载。使用模块化则无需考虑文件加载顺序。
3.按需加载。如果引用 Javascipt 文件较多,同时加载会花费加多时间。使用模块化可以在文件被依赖的时候被加载,而不是进入页面统一加载。
4.代码封装。将相同功能代码封装起来方便后续维护和复用。

2. 你知道哪几种模块化规范?

CommonJS

Node.js 采用了 CommonJS 模块规范。

CommonJS 规范规定,每个模块内部,module 变量代表当前模块。这个变量是一个对象,它的 exports 属性(即 module.exports )是对外的接口。加载某个模块,其实是加载该模块的 module.exports 属性。使用 require 方法加载模块。模块加载的顺序,按照其在代码中出现的顺序。

模块可以多次加载,但是只会在第一次加载时运行一次,然后运行结果就被缓存了,以后再加载,就直接读取缓存结果。要想让模块再次运行,必须清除缓存。

引入模块得到的值其实是模块输出值的拷贝,如果是复杂对象则为浅拷贝。

// a.js
let count = 1;
function inc() {count++;
}
module.exports = {count: count,inc: inc
};
// b.js
const a = require('./a.js');

console.log(a.count); // 1
a.inc();
console.log(a.count); // 1 

因为 CommonJS 输出的是值的浅拷贝,也就是说 count 在输出后就不再和原模块的 count 有关联。

在 Node 中每一个模块都是一个对象,其有一个 exports 属性,就是文件中指定的 module.exports,当我们通过 require 获取模块时,得到的就是 exports 属性。再看另一个例子:

// a.js
module.exports = 123;

setTimeout(() => {module.exports = 456;
}, 1000);

// b.js
console.log(require('./a.js')); // 123

setTimeout(() => {console.log(require('./a.js')); // 456
}, 2000); 

模块的 module.exports 值改变了,我们通过 require 获取模块的值也会发生变化。

CommonJS 使用了同步加载,即加载完成后才进行后面的操作,所以比较适合服务端,如果用在浏览器则可能导致页面假死。

AMD

AMD(Asynchronous Module Definition,异步加载模块定义)。这里异步指的是不堵塞浏览器其他任务(dom构建,css渲染等),而加载内部是同步的(加载完模块后立即执行回调)。 AMD 也采用 require 命令加载模块,但是不同于 CommonJS,它要求两个参数,依赖模块和回调:

require([module], callback); 

以 RequireJS 示例, 具体语法可以参考 requirejs.org/

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值