JavaScript代码模块化
- 隐藏模块内部实现
- 定义模块接口
- 解决依赖关系
利用对象、闭包和立即执行函数实现模块化
(function countClicks(){
let numClicks = 0;
document.addEventListener("Click", () => {
alert(++numClicks);
});
})(); // 立即执行
这段代码再整个文档中注册单击事件,每次单机时,变量numClicks
递增,并通过alert弹出框呈献给用户。
// 较上一段代码 定义了模块接口
const MouseCounterModule = function(){
let numClicks = 0;
const handleClick = () => {
alert(++numClicks);
};
return {
countClicks: () => {
document.addEventListener("click", handleClick);
}
};
}(); // 立即执行函数
这里返回了一个对象,可以通过这个对象来调用countClicks
方法。
// 模块拓展
const MouseCounterModule = function(){
let numClicks = 0;
const handleClick = ()=>{
alert(++numClicks);
};
return {
countClicks: () =>{
document.addEventListener(
"click", handleClick
);
}
};
}();
// 模块拓展, 拓展了一个scroll
(function(module){
let numScrolls = 0;
const handleScroll = () => {
alert(++numScrolls);
}
// 拓展模块接口
module.countScrolls = () => {
document.addEventListener(
"scroll", handleScroll
);
};
})(MouseCounterModule);
尽管这上面将countClicks
和countScrolls
都放进了MouseCounterModule
中,但是两个方法之间的数据却不能进行共享,这就出现了一个缺点。
因此,有了后面的一些解决办法。
使用AMD来模块化JavaScript应用
define("MouseCounterModule", ['jQuery'], $=>{
let numClicks = 0;
const handleClicks = ()=>{
alert(++numClicks);
};
return{
countClicks: () =>{
$(document).on("click", handleClicks)
}
};
});
AMD提供名为define
的函数,它接收以下参数:
- 新创建模块的ID
- 当前模块依赖的ID列表
- 初始化模块的工厂函数,该工厂函数接收依赖的模块列表作为参数
使用CommonJS来模块化JavaScript应用
AMD是基于浏览器的环境,而CommonJS的设计则是面向通用JavaScript环境,其使用基于文件的模块。
// MouseCounterModule.sj
const $ = require("jQuery");
let numClicks = 0;
const handleClick = () => {
alert(++numClicks);
}
module.exports = {
countClicks: () => {
$(document).on("click", handleClick);
}
};
而在另外一个文件中引用模块的时候代码如下:
const MouseCounterModule = require("MouseCounterModule");
MouseCounterModule.countClicks();
CommonJS语法简单,但是一般不支持浏览器环境,于是有了下面的ES6标准。
使用ES6标准
ES6模块的主要思想是必须显示地使用标识符导出模块,才能从外部访问模块。因此,ES6引入了两个关键字:
-
import
-
export
导入和导出功能
// ninja.js
const ninja = 'Yoshi';
// 通过export导出变量和函数
export const message = 'hello';
export function saiHiToNinja(){
return message + " " + ninja;
}
// 从ninja模块中导入
import {message, sayHiToNinja} from "ninja.js";
默认导出
通常我们不需要从模块中导出一组相关的标识符,只需要一个标识符来代表整个模块的导出。
// 默认导出
export default class Ninja{
constructor(name){
this.name = name;
}
}
export function compareNinjas(ninja1, ninja2){
return ninja1.name ==- ninja2.name;
}
下面是导入模块默认导出内容
// 导出默认的类
import ImportedNinja from "ninja.js";
// 上面是导入默认导出内容,可以使用任意名称,可以不使用花括号
import {compareNinjas} from "ninja.js";
// 上面是导入指定内容,也就是导入了那个非默认导出的函数
网友评论