JavaScript
大约 3 分钟
JavaScript
目录
模块系统
为什么要模块化
模块化 vs 旧模块化
为什么要模块化?
<script>
标签引入js脚本:全局变量同名冲突问题、引用脚本顺序问题
解决方案
- 解决方案v1:匿名函数闭包,但变量变得不可引用,代码不可复用
- 解决方案v2:匿名函数闭合的同时,返回一个值给对象实例
- 解决方案v3:模块化规范ES6 √
常用的模块化规范
- CommonJS
- AMD
- CMD
- ES6的Modules(不再需要闭包,文件就是模块)
模块化进化史
(1) 最早全写在js
function foo(){/*...*/}
function bar(){/*...*/}
// 原始写法
// 缺点:耦合度高,不方便管理。Global被污染,容易命名冲突
(2) 对象封装【Namespace模型】
(划分私有命名空间)
var myapp = {
foo:function(){}
bar:function(){}
}
myapp.foo();
// 解决:把变量的范围局限在对象里面
// 优点:减少Global变量数目
// 缺点:对象里的属性和方法很容易被修改掉,不安全
(3) 匿名闭包、立即执行函数【IIFF模型】
(划分私有命名空间)
(function(){
var foo = 111;
var bar = function () { return 222 }
return { bar: bar }
})();
// 解决:匿名函数闭包(将add的私有化到calculator中)
// 优点:可以保护好里面的属性和方法
// 缺点:不可调用内部函数、变量,无复用性
(4) 改进:使用模块作为出口
// ——————File_A:
var modeleA=(function(){
var foo = 111;
var bar = function () { return 222 }
return { bar: bar }
})();
// ——————File_B:
modeleA.bar(); // 222
modeleA.foo; // underfined
// 模块化基本封装,模块化雏形
模块化规范
服务器端规范
【CommonJS】√ Nodejs、webpack 遵循CommonJS规范
浏览器端规范
【AMD】 RequireJS 遵循AMD规范
【CMD】 SeaJS 遵循CMD规范
ALL
【ES6 module】√
模块化核心:导入和导出
模块功能
- 暴露部分接口给外部
- 划分作用域
具体实现
CommonJS
module.exports = { flag: true, test(a, b) {} }
前端三大框架
- Angular
- 09年诞生
- 让开发单页更方便
- 主要为前端带来 MVVM 开发模式,即数据驱动视图,不操作 DOM
- React
- Facebook开发
- 组件化
- Vue
- Vue作者:尤雨溪(华裔),早期由个人开发
- Angular
js模块化
js本身不支持模块化 require exports Node.js node中对js进行了特殊的模块化支持 CommonJS php可以直接'require', 'include' 可以使用API来进行文件与文件之间的依赖加载 浏览器也可以像node模块一样编程 '<script>' require.js AMD sea.js CMD
使用 - CommonJS
环境
CommonJS要在webpack里写(webpack依赖于node)
不然没有底层的东西去解析这个结构
导出
// multiple:
module.exports.foo = 'foo' // exports.foo = 'foo'
module.exports.app = 'app' // exports.app = 'app'
// 或
module.exports = {
foo = 'foo', // foo: foo, // foo,
app = 'app' // app: app // app
}
// Single:
module.exports = 'foo'
导入
const aaa = require('./aaa.js')
var flag = aaa.flag
var sum = aaa.sum
// 或
const {flag, sum} = require('./aaa.js')
使用 - ES6
载入(html里载入)
<script src="aaa.js" type="module"></script>
// html里导入,加module类型就不会有命名冲突
导出
export var flag = 100
export function sum () {}
export class Person {} // ES6的类
// 或
export {
flag, // flag: flag,
sum // sum: sum
}
// 或
export default [function () {}] // 只能有一个,无须加名字
导入(js里引用)
import {flag,sum} from './aaa.js'
// 或
import flag from './aaa.js'
// 或(全部导入)
import * as aaa from './aaa.js' // 用aaa.flag调用
使用
模块与导包
(原生不支持模块化,Nodejs(ES6)提供支持)
const express = require("express")