[JavaScript] 前端模块编程实现
前端模块化

前端早期写代码都是全局变量满天飞,这种情况会造成全局命名空间污染,变量冲突等问题
var a = 1;
var b = 2;
function c(){}
function d(){}
后来采用了 js 的对象写法,添加一个单独的命名空间
var space = {
a: 1,
b: 2,
c: function () {
console.log('我是c');
return this.a;
},
d: function () {
console.log('我是d');
return this.b;
},
};
console.log(space.a);
console.log(space.b);
console.log(space.c());
console.log(space.d());
这样就把变量挂载到 space 上了,而不是全局 window 上
亦或是挂载到原型上(构造函数)
function Class() {
this.a = 1;
this.b = 2;
}
Class.prototype.c = function () {
console.log('我是c');
return this.a;
};
Class.prototype.d = function () {
console.log('我是d');
return this.b;
};
var instance = new Class();
console.log(instance.a); //1
console.log(instance.b); //2
console.log(instance.c()); //我是c //1
console.log(instance.d()); // 我是d //2
面向对象一定程度上解决了命名冲突的问题,但是 js 没有私有变量,暴露内部变量,外部可有对内部数据进行修改外部可以修改内部数据
自执行函数(闭包)
(function (window) {
let a = 1;
let b = 2;
function c() {
console.log('我是c');
return a;
}
function d() {
console.log('我是d');
return b;
}
window.module = {
c:c,
d:d,
}
})(window);
//或者
var module = (function(){
let a = 1;
...
function c(){
...
}
...
return {
a:a,
c:c
}
})()
这一方式可以做到私有变量,模块的基本写法,比如 jquery
放大模式
(function () {
var a = 1;
window.module = {
c: function () {
return a
},
}
})();
(function (mod) {
var b = 2;
mod.d = function () {
return b
}
})(window.module)
console.log(module.c());
console.log(module.d());
console.log(module);
可以实现模块的分离和模块的继承,也具有私有变量,还可以将自执行函数拆分成多个文件进行加载,但是文件的执行顺序有一定的要求,要先声明对象 module
宽放大模式
//将上面给module添加功能的函数添加个默认值
(function (mod) {
var b = 2;
mod.d = function () {
return b
}
})(window.module || {})
可以将模块分成不同的文件,同时文件不用再考虑加载顺序不对导致 module 不存在的情况
- 引入外部的库
(function ($) {
var a = 'red';
$('.hello').css({ "background": a });
})(jQuery)
- 自执行函数
自执行函数中()分组操作符是用来将 function(){}这个函数声明转化为一种可以执行的表达式,单纯的 function(){}不是可执行的表达式,是一个函数声明
()分组操作符可以替换为其他操作符,比如 '#','+','-','!','void'......等等
//这样写也是可以的
+function ($) {
var a = 'red';
$('.hello').css({ "background": a });
}(jQuery)
- !function(){}();
- +function(){}();
- -function(){}();
- ~function(){}();
- ~(function(){})();
- void function(){}();
- (function(){}());
function(){}是函数声明,声明的是一个匿名函数,而(function(){})()是一个表达式,而 js 在预编译阶段会解释函数声明,确会忽略表达式.所以到(function(){})的时候,该表达式会返回一个匿名函数,之后该匿名函数遇到后面的(),便会被执行
var lis = document.querySelectorAll('li');
for(var i=0;i<5;i++){
lis[i].onclick = function(){
alert(i); //5,5,5,5,5
}
}
//又是这个经典的题目
//这题最简单还是用元素属性的方式去解决,比如
for(var i=0;i<5;i++){
lis[i].index = i;
lis[i].onclick = function(){
alert(this.index); //0,1,2,3,4
}
}
//还有就是闭包
for(var i=0;i<5;i++){
(function(i){
lis[i].onclick = function(){
alert(i); //0,1,2,3,4
}
})(i)
}
//闭包就是在循环中执行,将i的值保存到当前作用域中,当click绑定的函数触发时,会优先从离得最近的作用域去拿变量(就近原则)
//所以,使用其他的方式将当前i值保存到自己的作用域中就行
for(var i=0;i<5;i++){
click(i);
}
function click(i){
lis[i].onclick = function(){
alert(i); //0,1,2,3,4
}
}
//这其实就跟上面的闭包有些类似了,闭包取i是从上级的匿名函数的作用域中取保存的i,而该方式就是从click函数的作用域中去取i值
模块化的作用
- 解决全局变量污染的问题
- 一个文件一个模块,能够更快速定位问题和解决问题,方便维护
- 解决文件的依赖关系问题
- 使大型项目的开发过程中,每个人负责每个人的模块编写,方便大团队开发工作
参考
- 浏览器加载 CommonJS 模块的原理与实现
- Javascript 模块化编程(一):模块的写法
- JavaScript Module Pattern: In-Depth
- Seajs 与 RequireJS 的异同
- AMD 和 CMD 的区别有哪些?
- Common Module Definition / draft
- js-module-7day
[JavaScript] 前端模块编程实现的更多相关文章
- [JavaScript] 前端模块加载简单实现(require)
模块加载的简单实现 (function(win) { var baseUrl; var paths; var script_cache = {}; var script_queue = []; var ...
- 前端常用的库和实用技术之JavaScript面向切面编程
Aspect Oriented Programming(AOP)面向切面编程是一个比较热门的话题. AOP主要实现的目的是针对业务处理过程中的切面进行提取,它所面对的是处理过程 中的某个步骤或阶段,以 ...
- 翻译连载 |《你不知道的JS》姊妹篇 |《JavaScript 轻量级函数式编程》- 引言&前言
原文地址:Functional-Light-JS 原文作者:Kyle Simpson-<You-Dont-Know-JS>作者 译者团队(排名不分先后):阿希.blueken.brucec ...
- 翻译连载 | 第 10 章:异步的函数式(上)-《JavaScript轻量级函数式编程》 |《你不知道的JS》姊妹篇
原文地址:Functional-Light-JS 原文作者:Kyle Simpson-<You-Dont-Know-JS>作者 关于译者:这是一个流淌着沪江血液的纯粹工程:认真,是 HTM ...
- 翻译连载 | 第 10 章:异步的函数式(下)-《JavaScript轻量级函数式编程》 |《你不知道的JS》姊妹篇
原文地址:Functional-Light-JS 原文作者:Kyle Simpson-<You-Dont-Know-JS>作者 关于译者:这是一个流淌着沪江血液的纯粹工程:认真,是 HTM ...
- 翻译连载 | 第 11 章:融会贯通 -《JavaScript轻量级函数式编程》 |《你不知道的JS》姊妹篇
原文地址:Functional-Light-JS 原文作者:Kyle Simpson-<You-Dont-Know-JS>作者 关于译者:这是一个流淌着沪江血液的纯粹工程:认真,是 HTM ...
- 翻译连载 | 附录 A:Transducing(上)-《JavaScript轻量级函数式编程》 |《你不知道的JS》姊妹篇
原文地址:Functional-Light-JS 原文作者:Kyle Simpson-<You-Dont-Know-JS>作者 关于译者:这是一个流淌着沪江血液的纯粹工程:认真,是 HTM ...
- 翻译连载 | 附录 A:Transducing(下)-《JavaScript轻量级函数式编程》 |《你不知道的JS》姊妹篇
原文地址:Functional-Light-JS 原文作者:Kyle Simpson-<You-Dont-Know-JS>作者 关于译者:这是一个流淌着沪江血液的纯粹工程:认真,是 HTM ...
- 翻译连载 | 附录 B: 谦虚的 Monad-《JavaScript轻量级函数式编程》 |《你不知道的JS》姊妹篇
原文地址:Functional-Light-JS 原文作者:Kyle Simpson-<You-Dont-Know-JS>作者 关于译者:这是一个流淌着沪江血液的纯粹工程:认真,是 HTM ...
随机推荐
- HTML5标签汇总及知识学习线路总结
HTML5标签汇总,以及知识学习线路总结.
- Linux-3.0.8中基于S5PV210的GPIO模块代码追踪和分析
编写按键驱动时,想知道内核是如何管理GPIO的,所以开始追踪代码,中间走了一些弯路,现记录于此. 追踪代码之前,我猜测:第一,这部分代码应该在系统set up阶段执行:第二,GPIO的代码应该在mac ...
- U-Boot bootargs简析
Linux内核启动时需要一些配置信息,如根文件系统的类型.flash分区情况.串口终端的编号.内存的使用情况等等,而由于U-Boot和Linux Kernel的镜像是独立的两个文件,所以只能两者约定好 ...
- Solr Cloud
bin/solr start -cloud -s example/cloud/node1/solr -p 8983 -z node13:2181,node14:2181,node15:2181/usr ...
- Debian 9.x "stretch" 安装 vnStat 统计服务器流量
vnStat 是一款开源的 Linux 下统计网卡流量的软件,可以很方便地查看当前.当天.当月的流量统计报告,下面我们介绍下在 Debian 9.x 下安装 vnstat 的简单方法 首先,使用 ip ...
- 安装kylin的艰难历程
前言:暑假里老师布置的任务没有完成,来到学校后马不停蹄的安装kylin,结果一路艰难险阻,搞了快两个星期都没有弄好....现在止步于hive阶段卡死...仅将之前的步骤记录下来以便重新安装时更加顺利. ...
- MacOS使用Charles抓去HTTPS数据
1.安装Charles,示例版本为4.0.1 2.Proxy->Proxy Settings 3.MacOS->Terminal->ifconfig 获取本机IP地址,如192.16 ...
- 《JavaScript 高级程序设计》读书笔记三 基本概念
一 语法 区分大小写,驼峰式书写方式: 严格模式:“use strict”: 二 数据类型 a. 基本数据类型: undefined 声明变量未初始化 null 空指针,可以释放内存 Boole ...
- Windows 10 IoT Core 17133 for Insider 版本更新
今天,微软发布了Windows 10 IoT Core 17133 for Insider 版本更新,本次更新只修正了一些Bug,没有发布新的特性.用户可以登录Windows Device Porta ...
- 剑指offer面试题24:二叉搜索树的后序遍历序列
题目:输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历的结果.如果是返回true,否则返回false. 假设输入的数组任意两个数字都不相同 解题思路:二叉搜索树的特点是根节点的左子树的值小于等 ...