前端模块化

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

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. 网页偶现性崩溃-chrome

    简介: 项目前台框架:Angular2 + Bootstrap(日期等组件) + Echarts + 响应式(包括页面.字体缩放:rem) chrome版本:多个版本测试均有此问题. 表现: 订单详情 ...

  2. HTML5的Rang对象

    基本概念 Range对象代表页面上的一段连续的区域.通过Range对象,可以获取或修改网页上的任何区域. Selection与Range对象的使用 <body> <script> ...

  3. maven 项目快速下载jar方式

    maven仓库默认在国外,使用难免很慢,尤其是下载依赖的时候,换为国内镜像,让你感受飞一般的感觉.国内支持maven镜像的有阿里云,开源中国等,这里换为阿里云的. 修改maven配置文件setting ...

  4. 《python语言程序设计》_第三章(数字函数、字符串和对象)

    3.2_常见的Python函数 (1) abs()函数 求绝对值 (2) max(x1,x2,x3,....)求最大值 (3) min(x1,x2,x3,....)求最小值 (4) pow 返回a的b ...

  5. QEMU Networking

    QEMU Networking QEMU has a number of really nice ways to set up networking for its guests. It can be ...

  6. 2019-4-29 js学习笔记

    js学习笔记一:js数据类型   1:基本数据类型       number类型(整数,小数)      String类型          boolean类型        NaN类型其实是一个nu ...

  7. centos安装discuz论坛

    wget http://download.comsenz.com/DiscuzX/3.3/Discuz_X3.3_SC_UTF8.zip #下载最新版Discuzunzip Dis......zip ...

  8. Day3:html和css

    Day3:html和css 多类名选择器 样式的显示效果是跟html元素中的类名先后顺序无关,而是跟css样式的书写上下顺序有关. <!DOCTYPE html> <html lan ...

  9. 六、activiti工作流-流程定义查询

    本节主要讲流程定义查询.查询某个流程设计图片并保存到本地中.查询最新版本的流程定义集合.删除所有key相同的定义 先创建一个java类 package com.java.procdef; import ...

  10. 页面css样式找不到问题

    出现了一个页面没有样式的问题: 问题: 1.路径不对, 可以打开页面f12看样式是否找到 检查路径是否正确. 2.样式没引全或者没引对. 查看引入的样式是否正确或缺少样式. 3.路径明明写对了却404 ...