1. 首先,我们需要明白为什么要用模块化?

功能都是为了解决需求的。模块化可以带来的优点有以下几点:
(1)可维护性。举个例子,如果我们把未使用模块化的代码比作油和水混合在了一起,模块化之后的代码就好像油和水的分层,油就是油,水就是水,这样的代码层次清晰,功能分明。似乎用油和水必然分层的现象来指代JS模块化的大势所趋也很合适。
(2)命名空间。这里需要谈到JS的作用域。又涉及到了作用域链。如果对作用域链不熟悉的同学可以移步我的另一篇文章“理解JavaScript中的作用域链”。JS中是靠函数来区分作用域的。每个函数都有一个作用域链。如果我们把所有的代码都揉到一起,代码行数少还行,多了就难免会造成“命名空间污染”。
(3)可复用性。当我们明白了命名空间,借助命名空间我们就可以实现对模块代码的封装,这样我们就可以在任何我们需要这个功能的时候直接去引用这个功能模块。

接下来,用我的JS代码之路演示一下如何使代码模块化:
 
(1)原始时代:把所有的要用到的JS代码都堆砌在该页面的一对<script>标签中。
1 function f1(){
2 //函数体
3 }
4 function f2(){
5 //函数体
6 }
这样写的缺点:代码基本没有什么复用性可以,应该还会存在和页面隅合度太高的问题。还需要去考虑各种作用域的问题。
 
(2)古时代:思路就是把模块写成一个对象。比如我们要写一个能控制页面音乐播放,停止,下一首,上一首的功能。就可以封装一个musicPlayer对象
 1 // 将基本的方法封装起来
2 var musicPlayer = {
3
4 var musicDom = null, //播放器对象
5 var musicList = [], //存放歌曲列表
6
7 // 初始化音乐播放器
8 var init = function(){
9
10 },
11
12 // 添加一首歌曲
13 var add = function(src){
14
15 },
16
17 // 根据数组下标决定播放哪一首,索引index从0开始
18 var play = function(index){
19
20 },
21
22 // 暂停播放
23 var stop = function(){
24
25 },
26
27 // 下一首
28 var next = function(){
29
30 },
31
32 // 上一首
33 var prev = function(){
34
35 }
36 };
这时候,就已经可以称之为一个模块了,在全局作用域中,我们只向window对象上绑定了一个musicPlayer对象,之后我们就可以使用musicPlayer加'.'的形式来调用里面的方法。如“musicPlayer.init();”
这种方式也有一个缺点,就是我们不能去控制我们想暴露的内容,并且在外部可以改写musicPlayer对象的内部方法和变量。
 
(3)现代。包含IIFE(立即执行函数),放大模式,宽放大模式,输入全局变量
  
  除了IIFE,其他的三种我之前都没有接触过,在这里简单谈谈我的理解。
 
- IIFE(Immediately-Invoked Function Expression)
 1 // 创建一个立即执行的匿名函数
2 // 该函数返回一个对象,包含你要暴露的属性
3 // 如下代码如果不使用立即执行函数,就会多一个属性i
4 // 如果有了属性i,我们就能调用counter.i改变i的值
5 // 对我们来说这种不确定的因素越少越好
6
7 var counter = (function(){
8 var i = 0;
9
10 return {
11 get: function(){
12 return i;
13 },
14 set: function( val ){
15 i = val;
16 },
17 increment: function() {
18 return ++i;
19 }
20 };
21 }());
22
23 // counter其实是一个对象
24
25 counter.get(); // 0
26 counter.set( 3 );
27 counter.increment(); // 4
28 counter.increment(); // 5
29
30 counter.i; // undefined i并不是counter的属性
31 i; // ReferenceError: i is not defined (函数内部的是局部变量)

从以上的代码可以看出,counter中其中并没有i这个属性,它只有return 中暴露出来的内容。这样我们就对i实现了私有。

 
- 放大模式
我对放大模式的理解就是把原函数当作参数传递到IIFE中,然后给原函数添加新的扩展方法,把扩展后的函数返回。就实现了对原函数的“放大”。
1 var module1 = (function (mod){
2   mod.m3 = function () {
3     //...
4   };
5   return mod;
6 })(module1);

在这个例子中,就给module1添加了一个新的方法m3并返回。

- 宽放大模式
宽放大模式就是在放大模式的基础上新增了一个特性:IIFE的参数可以是空对象。
1 var module1 = ( function (mod){
2   //...
3   return mod;
4 })(window.module1 || {});

IIFE传入的参数:如果window.module1有定义,就传入该参数,如果为undefined就传入一个空对象。

- 输入全局变量
如果我们要在IIFE内使用全局变量,最好把全局变量通过参数传递进去。
1 var module1 = (function ($, YAHOO) {
2   //...
3 })(jQuery, YAHOO);

如上所示的代码将jQuery和YUI两个库的全局变量当作参数传入了module1。

转载https://www.cnblogs.com/enjoymylift/p/6030244.html

JavaScript模块化思想的更多相关文章

  1. JavaScript模块化思想之入门篇

    在写正文之前先写一点废话,从我大三下学期正式接触前端到现在,已经六个月了.自己从HTML,CSS,简单的JS验证开始,一点点开始走入前端的世界.越发的感觉前端这一领域散发着无穷的魅力,也许这和我真心喜 ...

  2. JavaScript模块化思想requireJS的使用

    1. 使用require.js的意义   (1)实现JS文件的异步加载,避免网页因为加载JS文件缓慢造成网页未响应 (2)管理模块之间的依赖性,便于代码的编写和维护.页面中只需要引入require.j ...

  3. JavaScript模块化思想之CommonJS、AMD、CMD、UMD

    前一篇文章了解了什么是模块,这一篇就简单介绍一下如何定义并加载一个模块. 我所了解的三种模块加载方式分别是CommonJS.AMD和CMD 网上关于这三种模块加载方式讲解的文章很多,我就简单的做个介绍 ...

  4. javascript模块化编程思想、实现与规范

    随着BS架构的发展,网站逐渐变成了互联网应用程序,嵌入网络的JavaScript代码越来越庞大,越来越复杂(业务逻辑处理或用户交互很多写在前端).网页越来越像桌面程序,需要一个团队分工协作.进度管理. ...

  5. javascript模块化应用

    这是一篇关于js模块化历程的长长的流水账,记录js模块化思想的诞生与变迁,展望ES6模块化标准的未来.经历过这段历史的人或许会感到沧桑,没经历过的人也应该知道这段历史. 无模块时代 在ajax还未提出 ...

  6. JavaScript模块化---AMD规范

    JavaSript模块化 在了解AMD,CMD规范前,还是需要先来简单地了解下什么是模块化,模块化开发?     模块化是指在解决某一个复杂问题或者一系列的杂糅问题时,依照一种分类的思维把问 题进行系 ...

  7. Javascript模块化开发-轻巧自制

    Javascript模块化开发-轻巧自制 一.前言现在javascript的流行,前端的代码越来越复杂,所以我们需要软件工程的思想来开发前端.模块化是必不可少的,这样不仅能够提高代码的可维护性.可扩展 ...

  8. 实现一个JavaScript模块化加载器

    对任何程序,都存在一个规模的问题,起初我们使用函数来组织不同的模块,但是随着应用规模的不断变大,简单的重构函数并不能顺利的解决问题.尤其对JavaScript程序而言,模块化有助于解决我们在前端开发中 ...

  9. JavaScript模块化开发&&模块规范

    在做项目的过程中通常会有一些可复用的通用性功能,之前的做法是把这个功能抽取出来独立为一个函数统一放到commonFunctions.js里面(捂脸),实现类似于snippets的代码片段收集. fun ...

随机推荐

  1. C# Why does '+' + a short convert to 44

    I have a line of code that looks like this: MyObject.PhoneNumber = '+' + ThePhonePrefix + TheBizNumb ...

  2. CSS外观属性

    CSS外观属性 color 文本颜色 line-height 行间距 text-aline水平对齐方式 text-indent 首行缩进 letter-spacing字间距 word-spacing ...

  3. python中收集函数的解包问题

    收集参数的解包问题 - 把参数放入list或者字典中,直接把list/dict中的值放入收集参数中- 语法:参照案例 # 收集参数的问题 def stu(*args): print("=&q ...

  4. 2018-01-15 History in Threads: 火狐插件实现浏览历史按主题显示(树)

    History in Threads似乎是唯一一个业余项目里有确认用户的. 大部分JavaScript源码(300+行)也用了中文命名. 插件功能很简单, 就是根据网页点击顺序生成树, 每个树可以认为 ...

  5. ArcGIS地图文档优化 mxdPerfstat工具使用体验

    经常有客户会咨询到如何提高地图的显示性能.为何ArcMap刷新地图那么缓慢.为何地图服务响应要等待10多秒? 诸如这些问题,虽然它们的表象都是相似的,但是往往在分析排查问题的时候,我们发现背后的原因是 ...

  6. linux 开机自启动脚本

    在/etc/rc.local文件中添加自启动命令(其中一种方法) 1.案例,就用博主本人之前发的博文 “nginx + flask + uwsgi + centos + python3 搭建web项目 ...

  7. SQL Server的一个不显眼的功能 备份文件的分割

    SQL Server的一个不显眼的功能 备份文件的分割 当完整备份数据库的时候,我们有时候可能会遇到一种极端情况,比如服务器上C,D,E三个盘符都只剩下5G空间了 但是如果要完整备份业务库需要12G的 ...

  8. 洗礼灵魂,修炼python(49)--巩固篇—包

    包(Package) 这个其实前面也说过的,不过同模块一样,没有具体的解析 1.什么是包 在创建许许多多模块后,我们可能希望将某些功能相近的文件组织在同一文件夹下,那么此文件夹(目录)即为包,文件夹( ...

  9. python第五十二天---第九周作业 类 Fabric 主机管理程序

    类 Fabric 主机管理程序开发:1. 运行程序列出主机组或者主机列表2. 选择指定主机或主机组3. 选择让主机或者主机组执行命令或者向其传输文件(上传/下载)4. 充分使用多线程或多进程5. 不同 ...

  10. entity framework异常 The specified cast from a materialized 'System.Int32' type to the 'System.String' type is not valid

    ROW_NUMBER() OVER (ORDER BY (select Null)) AS Id entity framework 查询中有这句会有异常