在写正文之前先写一点废话,从我大三下学期正式接触前端到现在,已经六个月了。自己从HTML,CSS,简单的JS验证开始,一点点开始走入前端的世界。越发的感觉前端这一领域散发着无穷的魅力,也许这和我真心喜爱前端分不开。有些人总爱说前端技术迭代快,认为这是前端的一个缺点,但我恰恰认为这正是前端的魅力所在,充满着朝气和活力。


小小感慨一下,现在开启我的JavaScript模块化入门之旅,之前自己做的都是小项目,简单的写写JS验证,给按钮添加一些绑定事件等等。随着自己对JS学习和使用的深入,渐渐的发现两个问题:
    (1)我之前写的JS代码重用性很低
    (2)功能分散,举个栗子,我要获取当前日期,也要获取当前日期加1也就是明天的日期,之前我作为两个独立互不相干的函数去写,但现在想想,其实他们都可以归为一个日期对象的两个方法,把它们绑定在一个对象上,作为它的两个方法,不是更好么?

如果想好好了解一下JavaScript模块化,推荐阮一峰老师的文章。

 
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(); //
  26. counter.set( 3 );
  27. counter.increment(); //
  28. counter.increment(); //
  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。

 

JavaScript模块化思想之入门篇的更多相关文章

  1. javascript模块化编程 从入门到实战

    <!DOCTYPE html> <html lang="zh-cn"> <head> <meta charset="UTF-8& ...

  2. JavaScript模块化思想

    1. 首先,我们需要明白为什么要用模块化? 功能都是为了解决需求的.模块化可以带来的优点有以下几点: (1)可维护性.举个例子,如果我们把未使用模块化的代码比作油和水混合在了一起,模块化之后的代码就好 ...

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

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

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

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

  5. 造轮子和用轮子:快速入门JavaScript模块化

    造轮子和用轮子:快速入门JavaScript模块化 前言 都说“不重复造轮子”,就像iPhone——它除了打电话还可以播放音乐——但是工程师不用从零开始做一个音乐播放功能,也许只要在iPhone的系统 ...

  6. JavaScript入门篇 编程练习

    编程挑战 一.定义"改变颜色"的函数 提示: obj.style.color obj.style.backgroundColor 二.定义"改变宽高"的函数 提 ...

  7. 慕课网JavaScript入门篇课程笔记

    1.js注释很重要 单行注释,在注释内容前加符号 “//”. <script type="text/javascript"> document.write(" ...

  8. 开心菜鸟系列----函数作用域(javascript入门篇)

      1 <!DOCTYPE html>   2 <html>   3 <script src="./jquery-1.7.2.js"></ ...

  9. 开心菜鸟系列----变量的解读(javascript入门篇)

                       console.info(         console.info(window['weiwu'])          console.info(window. ...

随机推荐

  1. python学习之老男孩python全栈第九期_day009作业

    1. 写函数,检查获取传入列表或元组对象的所有奇数位索引对应的元素,并将其作为新列表返回给调用者. 答: l1 = [] def odd(li): for i in range(1,len(li),2 ...

  2. 集合框架二(Collection接口实现类常用遍历方法)

    四种常用遍历方式 Collection coll = new ArrayList(); coll.add("123"); coll.add("456"); co ...

  3. HTML5 简单归纳 -- 前端知识 (二)

    HTML5 全屏事件 全屏事件:requestFullScreen 关闭全屏:cancelFullScreen 判断是否全屏:fullScreenElement 注意:现各大主流浏览器中由于内核不同的 ...

  4. art-template辅助函数和子模板

    art-template 前端使用 用途:主要用来处理数据和优化性能,与其他的一些模块化处理数据的插件相比,art-template处理性能好 不废话,上代码 1.art-template基本语法使用 ...

  5. JS--我发现,原来你是这样的JS(三)(基础概念--灵魂篇)

    一.介绍 这是红宝书(JavaScript高级程序设计 3版)的读书笔记第三篇(灵魂篇介绍),有着剩下的第三章的知识内容. 红宝书这本书可以说是难啃的,要看完不容易,挺厚的,要看懂更不容易,要熟练js ...

  6. php对文件的操作

    如何让自己磁盘中的文件夹和目录显示在网页上?那就来看一下,用php是怎么来操作他们的吧 php中文件,一般包含两块内容,文件和目录先来一句一句的看代码,及他的作用 运行后看一下结果 file 指的是文 ...

  7. android 电话监听和拦截

    一.首先在manifest.xml文件中获取监听电话权限,注册监听电话的Activity <receiver android:name=".PhoneReceiver"> ...

  8. Double Array Trie 的Python实现

    不多介绍,可自行Google,或者其它关键词: "datrie" 放代码链接: double_array_trie.py 因为也是一段学习代码,参考的文章都记在里面了,主要参考gi ...

  9. 基于MD5的增强型摘要算法

    message-digest algorithm 5(信息-摘要算法),md5的长度,默认为128bit,也就是128个0和1的二进制串.但是,这样表达是很不友好的,所以将二进制转成了16进制,每4个 ...

  10. Supervisor 管理进程,Cloud Insight 监控进程,完美!

    Supervisor 是由 Python 语言编写.基于 linux 操作系统的一款服务器管理工具,用于监控服务器的运行,发现问题能立即自动预警及自动重启等. Cloud Insight 是一款次世代 ...