栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 前沿技术 > 大数据 > 大数据系统

面经-AMD / CMD / UMD / CommonJS / ES Module

面经-AMD / CMD / UMD / CommonJS / ES Module

这里写目录标题
    • 1. CommonJS
    • 2.ES Module
    • 3. AMD
    • 4.CMD
    • 5.UMD
    • 总结

请你讲一下对于JS中模块的理解,Commonjs、 AMD和CMD分别有什么特点?
一个模块是能实现特定功能的文件,有了模块就可以方便的使用别人的代码,想要什么功能就能加载什么模块。
模块化开发方便代码的管理,提高代码复用性,降低代码耦合,每个模块都会有自己的作用域,当前流行的模块化规范有CommonJS,AMD,CMD,ES6的import;

1. CommonJS

CommonJS的主要实践者就是nodejs;一般对模块输出用module.exports去输出,用require去引入模块, CommonJS一般采用同步加载 ;CommonJS 模块输出的是一个值的拷贝;
EG:
1° 对于基本数据类型, CommonJS 模块无论加载多少次, 都只会在第一次加载时运行一次, 以后再加载, 返回的都是第一次运行结果的缓存, 除非手动清除系统缓存;

 mod.incCounter() 不会影响 mod.counter,
// lib.js
var counter = 3
function incCounter() {
counter++
}
module.exports = {
counter: counter,
incCounter: incCounter,
}

// main.js
var mod = require('./lib')
console.log(mod.counter) // 3
mod.incCounter()
console.log(mod.counter) // 3

2° 如果是个对象, 修改里面的值, 会影响原对象

// lib.js
var obj = { name: 'Yancey', age: 18 }
function incCounter() {
 obj.name = 'Leo'
}
module.exports = {
 obj: obj,
 incCounter: incCounter,
}

// main.js
var mod = require('./lib')
console.log(mod.obj) // { name: 'Yancey', age: 18 }
mod.incCounter()
console.log(mod.obj) // { name: 'Leo', age: 18 }

3°如果把对象改成其他类型, 原变量不受响应.

// lib.js
var obj = { name: 'Yancey', age: 18 }
function incCounter() {
  obj = '沙雕'
}
module.exports = {
  obj: obj,
  incCounter: incCounter,
}

// main.js
var mod = require('./lib')
console.log(mod.obj) // { name: 'Yancey', age: 18 }
mod.incCounter()
console.log(mod.obj) // { name: 'Yancey', age: 18 }

// lib.js

2.ES Module

1° ES6 模块输出的是值的引用
JS 引擎对脚本静态分析的时候, 遇到模块加载命令 import 就会生成一个只读引用. 等到脚本真正执行的时候, 再根据这个只读引用到被加载的模块中取值. 因此, ES6 模块是动态引用, 并且不会缓存值, 模块里的变量绑定其所在的模块.

// lib.js
export let counter = 3
export function incCounter() {
  counter++
}

// main.js
//只读引用 counter
import { counter, incCounter } from './lib'
//模块中取值
console.log(counter) // 3
incCounter()
//不会缓存值
console.log(counter) // 4

2° ES6 输入的模块变量只是一个"符号连接", 所以这个变量是只读的, 对它重新赋值会报错

// lib.js
export let obj = {}

// main.js
import { obj } from './lib'
obj.prop = 123 // 可以
obj = {} // 报错
3. AMD

AMD主要采用异步加载模式,AMD的主要实践有require.js

使用 require.js

// 定义没有依赖的模块
define(function () {
  return 模块
})

// 定义有依赖的模块
define(['module1', 'module2'], function (m1, m2) {
  return 模块
})

//引入使用模块
require(['module1', 'module2'], function (m1, m2) {
  // 使用m1/m2
})

4.CMD

CMD是主要实践是Sea.js,与AMD相似,AMD依赖前置加载,提前加载执行,CMD就近加载,延迟加载 AMD用户体验好,因为模块提前执行了;CMD性能好,因为只有用户需要的时候才执行。
使用 sea.js

// 定义没有依赖的模块
define(function (require, exports, module) {
  exports.xxx = value
  module.exports = value
})

// 定义有依赖的模块
define(function (require, exports, module) {
  // 引入依赖模块(同步)
  var module2 = require('./module2')
  // 引入依赖模块(异步)
  require.async('./module3', function (m3) {})
  // 暴露模块
  exports.xxx = value
})

// 引入使用模块
define(function (require) {
  var m1 = require('./module1')
  var m4 = require('./module4')
  m1.show()
  m4.show()
})
5.UMD

所谓UMD (Universal Module Definition), 就是一种 Javascript 通用模块定义规范, 让你的模块能在 Javascript 所有运行环境中发挥作用.

总结

1.CommonJS 与 ES6 Module
CommonJS 是运行时加载, 这种特性不能使用 Tree-shaking; ES6 Module 是编译时输出接口, 可使用 Tree-shaking

2.CMD 和 AMD 的异同
相同点: 都是异步加载
不同点: AMD 依赖前置, 提前执行, js 可以方便知道依赖模块是谁, 立即加载; 而 CMD 就近依赖, 需要使用把模块变为字符串解析一遍才知道依赖了那些模块

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/342410.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号