前端模块化

前端早期写代码都是全局变量满天飞,这种情况会造成全局命名空间污染,变量冲突等问题

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值

模块化的作用

  1. 解决全局变量污染的问题
  2. 一个文件一个模块,能够更快速定位问题和解决问题,方便维护
  3. 解决文件的依赖关系问题
  4. 使大型项目的开发过程中,每个人负责每个人的模块编写,方便大团队开发工作

参考

[JavaScript] 前端模块编程实现的更多相关文章

  1. [JavaScript] 前端模块加载简单实现(require)

    模块加载的简单实现 (function(win) { var baseUrl; var paths; var script_cache = {}; var script_queue = []; var ...

  2. 前端常用的库和实用技术之JavaScript面向切面编程

    Aspect Oriented Programming(AOP)面向切面编程是一个比较热门的话题. AOP主要实现的目的是针对业务处理过程中的切面进行提取,它所面对的是处理过程 中的某个步骤或阶段,以 ...

  3. 翻译连载 |《你不知道的JS》姊妹篇 |《JavaScript 轻量级函数式编程》- 引言&前言

    原文地址:Functional-Light-JS 原文作者:Kyle Simpson-<You-Dont-Know-JS>作者 译者团队(排名不分先后):阿希.blueken.brucec ...

  4. 翻译连载 | 第 10 章:异步的函数式(上)-《JavaScript轻量级函数式编程》 |《你不知道的JS》姊妹篇

    原文地址:Functional-Light-JS 原文作者:Kyle Simpson-<You-Dont-Know-JS>作者 关于译者:这是一个流淌着沪江血液的纯粹工程:认真,是 HTM ...

  5. 翻译连载 | 第 10 章:异步的函数式(下)-《JavaScript轻量级函数式编程》 |《你不知道的JS》姊妹篇

    原文地址:Functional-Light-JS 原文作者:Kyle Simpson-<You-Dont-Know-JS>作者 关于译者:这是一个流淌着沪江血液的纯粹工程:认真,是 HTM ...

  6. 翻译连载 | 第 11 章:融会贯通 -《JavaScript轻量级函数式编程》 |《你不知道的JS》姊妹篇

    原文地址:Functional-Light-JS 原文作者:Kyle Simpson-<You-Dont-Know-JS>作者 关于译者:这是一个流淌着沪江血液的纯粹工程:认真,是 HTM ...

  7. 翻译连载 | 附录 A:Transducing(上)-《JavaScript轻量级函数式编程》 |《你不知道的JS》姊妹篇

    原文地址:Functional-Light-JS 原文作者:Kyle Simpson-<You-Dont-Know-JS>作者 关于译者:这是一个流淌着沪江血液的纯粹工程:认真,是 HTM ...

  8. 翻译连载 | 附录 A:Transducing(下)-《JavaScript轻量级函数式编程》 |《你不知道的JS》姊妹篇

    原文地址:Functional-Light-JS 原文作者:Kyle Simpson-<You-Dont-Know-JS>作者 关于译者:这是一个流淌着沪江血液的纯粹工程:认真,是 HTM ...

  9. 翻译连载 | 附录 B: 谦虚的 Monad-《JavaScript轻量级函数式编程》 |《你不知道的JS》姊妹篇

    原文地址:Functional-Light-JS 原文作者:Kyle Simpson-<You-Dont-Know-JS>作者 关于译者:这是一个流淌着沪江血液的纯粹工程:认真,是 HTM ...

随机推荐

  1. [swarthmore cs75] Compiler 2 – Boa

    课程回顾 Swarthmore学院16年开的编译系统课,总共10次大作业.本随笔记录了相关的课堂笔记以及第4次大作业. A-Normal Form 在80年代,函数式语言编译器主要使用Continua ...

  2. UML model refactoring: a systematic literature review

    一.基本信息 标题:UML model refactoring: a systematic literature review 时间:2015 出版源:Empirical Software Engin ...

  3. 【repost】javascript callback

    在javascript中回调函数非常重要,它们几乎无处不在.像其他更加传统的编程语言都有回调函数概念,但是非常奇怪的是,完完整整谈论回调函数的在线教程比较少,倒是有一堆关于call()和apply() ...

  4. lambada

    一.动态创建 ParameterExpression parameter = Expression.Parameter(typeof(User), "u"); //创建委托 Mem ...

  5. 如何高效地写CSS--等以后有空多加总结一下

    CSS写的并不多,如果从零开始的项目,自己一定想搬砖来得容易点.CSS编写一定有其工程化的方法,来时编写更加有效率. 考虑将CSS的预处理LESS.Sass或Stylus引入,或者将CSS的后处理Po ...

  6. spring整合mybatis二种配置

    第一种: <!-- 配置sqlsession --> <bean id="sqlsessionFactory" class="org.mybatis.s ...

  7. Javascript高级编程学习笔记(16)—— 引用类型(5) Function类型

    JS中许多有趣的地方都和函数脱不了联系 那么是什么让JS中的函数这么有趣呢? 我们一起来看看吧 Function类型 在JS中函数实际上就是对象,每个函数都是Function类型的实例,和JS的其他引 ...

  8. FragmentTabHost用法

    FragmentTabHost组成 Tabhost,TabWidget,切换的内容容器FrameLayout 层级关系 ----FragmentTabHost |-----TabWidget |--- ...

  9. Kali学习笔记27:Burpsuite(上)

    文章的格式也许不是很好看,也没有什么合理的顺序 完全是想到什么写一些什么,但各个方面都涵盖到了 能耐下心看的朋友欢迎一起学习,大牛和杠精们请绕道 如果我只能选择一款工具进行Web渗透,那么一定就是Bu ...

  10. springbean的生命周期

    1.Spring对Bean进行实例化(相当于程序中的new Xx())2.Spring将值和Bean的引用注入进Bean对应的属性中3.如果Bean实现了BeanNameAware接口,Spring将 ...