`
longgangbai
  • 浏览: 7325426 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

【转】JavaScript编程模式:模块的力量

 
阅读更多

 

 

块模式是一个常用的JavaScript编程模式。它很好理解,但是还有一些高级的使用方法没有引起广泛的注意。如果你已经非常了解模块模式,可以跳到"高级模式"的段落。

51CTO推荐阅读:JavaScript中的函数式编程实践

匿名闭包

匿名闭包是让一切成为可能的基础,而且这也是JavaScript最好的特性。我们创建个简单的匿名函数看看。函数内运行的代码都存在于闭包内,这个闭包在整个应用的生命周期内都保持私密和自己的状态。(相关阅读:揭开Javascript闭包的真实面目

(function () {   
    // 所有的var和function都只存在于当前作用域内   
    // 仍然可以读取到所有的全局变量   
    }());  
 

    注意:包住匿名函数的"()"。这是JavaScript语言本身的要求,因为由function开头的代码一律被识别为"函数声明",用()包住则创建了一个函数表达式。

    引用全局变量

    JavaScript有个特质隐含的全局变量。无论一个name是否使用过,JavaScript解释器反向遍历作用域链查找这个name的var 声明,如果没找到var,则这个对象是全局的。这意味着在一个匿名闭包中使用和创建全局变量很容易。不幸的是这让代码难与管理,对阅读代码的人来说很难区 分哪些变量是全局的。幸好,我们的匿名函数提供了一个简单的替代方案。将全局变量作为参数传入匿名函数,这比用隐含全局变量更清晰更快速。例子:

    (function ($, YAHOO) {   
        // 使用全局的 jquery 比如$ 和 YAHOO   
        }(jQuery, YAHOO));  
     

     

    当你不仅仅想使用全局变量,还想声明一些(全局变量)的时候。我们可以很方便地用匿名函数的返回值来导出(全局变量)。 这么做就是一个完整的模块模式基本形态。例子:

    var MODULE = (function () {   
        var my = {},   
        privateVariable = 1;   
        function privateMethod() {   
        // …   
        }   
        my.moduleProperty = 1;   
        my.moduleMethod = function () {   
        // …   
        };   
        return my;   
        }());  
     

    高级模式

    上面的内容对大多数用户已经很足够了,但我们还可以基于此模式发展出更强大,易于扩展的结构。

    增生

    模块模式的一个限制是整个模块必须写在一个文件里。在大型编码项目里工作的人都知道代码分成多个文件的重要性。幸好,我们又一个很好的解决方案。首先,我们导入模块,然后我们添加属性,然后我们再把它导出。例子:

    var MODULE = (function (my) {   
        my.anotherMethod = function () {   
        //添加一些方法   
        };   
        return my;   
        }(MODULE));  
     

    松散增生

    我们的上一个例子要求我们的初始化模块必须先运行。而增生必须第二步发生。这不应该是必要的。JavaScript的好处之一就是可以异步的读取脚 本文件。我们可以创建灵活的多块的模块,用Loose Augmentation,他们可以按任何顺序加载自己。每个文件应该有如下的结构:

     

    var MODULE = (function (my) {   
        // 添加一些功能   
        return my;   
        }(MODULE || {}));  
     

     

     

     

     

       

      紧密增生

      虽然松散增生很牛叉,但是这对你的模块有一定的限制。最重要的是你不能安全的重载(override)你的模块属性.你也不能在初始化的时候就使用模块的属性。紧密增生包含一个加载顺序,但是允许重载(override).例子:

      var MODULE = (function (my) {   
          var old_moduleMethod = my.moduleMethod;   
          my.moduleMethod = function () {   
          // 重载方法,可通过old_moduleMethod调用旧的方法   
          };   
          return my;   
          }(MODULE));  
       

      这样我们重载(override)了MODULE.moduleMethod,但如果需要,仍可保持对原方法的引用。

      Cloning and Inheritance 克隆和继承   
          var MODULE_TWO = (function (old) {   
          var my = {},   
          key;   
          for (key in old) {   
          if (old.hasOwnProperty(key)) {   
          my[key] = old[key];   
          }   
          }   
          var super_moduleMethod = old.moduleMethod;   
          my.moduleMethod = function () {   
          //在克隆里重载方法,通过super_moduleMethod接入父级(super)   
          };   
          return my;   
          }(MODULE));  
       

       

       

        这个模式可能是最灵活的选择。他允许一些neat compositions。这会带来一些灵活性上的代价。

        跨文件私有状态

        将一个模块划分到多个文件的限制之一是每个文件保持它自己的私有状态,而且不能解接入其他文件的私有状态。这是可以解决的,下面的例子用松散增生模块在多个增生之间保持私有状态:

        var MODULE = (function (my) {   
        var _private = my._private = my._private || {},   
        _seal = my._seal = my._seal || function () {   
        delete my._private;   
        delete my._seal;   
        delete my._unseal;   
        },   
        _unseal = my._unseal = my._unseal || function () {   
        my._private = _private;   
        my._seal = _seal;   
        my._unseal = _unseal;   
        };   
        // 持久的接入 _private, _seal, 和 _unseal   
        return my;   
        }(MODULE || {})); 
         

          任何文件都可以对他们的局部变量_private设属性,并且设置对其他的文件也立即生效。一旦这个模块加载结束,应用会调用 MODULE._seal()"上锁",这会阻止外部接入内部的_private。如果这个模块需要再次增生,应用的生命周期内,任何文件都可以调用 _unseal() ”开锁”,然后再加载新文件。加载后再次调用 _seal()”上锁”。

          子模块

          我们最后的高级模式是最简单的,有很多好例子来创建子模块,就像创建一个普通的模块:

          尽管这很明显,但我认为还是值得加进来的,子模块具有一般模块所有的高级能力,包括增生和私有状态。

          MODULE.sub = (function () {   
              var my = {};   
              // …   
              return my;   
              }());  
           

          总结

          大多数高级模式可以与其他的互相组合形成有用的模式。如果让我来设计一个复杂应用的架构,我会组合使用loose augmentation, private state, 和 sub-modules.
          这里我并没有研究性能问题。但是我想顺便提一句:模块模式效率很好。代码量可以更少,使加载代码更快。使用 loose augmentation允许简单的非阻碍式并行加载,这更可以提升下载的速度。初始化时间可能比其他方法要慢,但是这是值得的。

          最后,这里有个sub-module动态的把自己加载到父模块去(如果没有则创建)。为了简洁,这里没有包含private state。这段代码允许一个复杂的大型分层代码库并行的加载自己和它的子模块:

          var UTIL = (function (parent, $) {   
              var my = parent.ajax = parent.ajax || {};   
              my.get = function (url, params, callback) {   
              // ok, so I’m cheating a bit    
              return $.getJavaScriptON(url, params, callback);   
              };   
              // etc…   
              return parent;   
              }(UTIL || {}, jQuery));  
           
            分享到:
            评论
            1 楼 dufangpu 2014-09-25  
            为什么这么叼

            相关推荐

              javascript王者归来 书中的examples

              《JavaScript王者归来》是一本深度探讨JavaScript编程技术的著作,其核心理念是帮助读者深入理解JavaScript的本质,提升编程技能,并在实际开发中发挥出强大的力量。书中的"examples"部分,是作者为了辅助阐述概念、...

              JavaScript 语言参考 中文版 (CHM.rar

              5. 异步编程:JavaScript支持回调函数、Promise和async/await等异步编程模式,使得在执行过程中能同时处理多个任务。 JavaScript在Web开发中的应用广泛,包括: 1. 客户端脚本:JavaScript可以修改HTML元素,实现...

              Javascript函数式编程语言

              总结来说,JavaScript的函数式编程特性提供了编写简洁、可维护代码的强大力量。通过理解和应用函数式编程的核心概念,我们可以编写出模块化、高复用性以及高度数学正确的代码,这将极大地提升开发效率和程序质量。...

              一款很使用的JavaScript教程

              6. **面向对象编程**:JavaScript支持基于原型的对象创建和类的模拟,包括构造函数、原型链、闭包和模块模式。 7. **ES6新特性**:介绍ECMAScript 6(也称为ES2015)的新特性,如箭头函数、模板字符串、解构赋值、...

              javascript基础知识大全

              异步编程是JavaScript处理I/O操作的关键,如Ajax(异步JavaScript和XML)用于后台通信,async/await提供更简洁的异步编程模式。 12. **ES6及后续版本新特性** ES6引入了许多新特性,如类(class)、模板字符串、...

              基于APPCAN制作的一款Hibird类型的APP,APP的编程语言是HTML5+CSS3+JavaScript.zip

              - **Vue/React/Angular等框架**:基于JavaScript的前端框架,提供了MVVM或组件化开发模式,优化了大型应用的构建和维护。 4. APPCAN介绍: APPCAN是一款跨平台的移动应用开发工具,它允许开发者使用HTML5、CSS3和...

              JavaScript大全

              JavaScript是一种广泛应用于网页和网络应用的脚本语言,它由网景公司的Brendan Eich在1995年发明,起初被设计为增强网页的...通过深入学习和实践,你将能够利用JavaScript的力量创造出富有互动性和创新性的Web应用。

              TypeScript开发手册(极其适合C#开发人员)

              由于TypeScript的出现,开发者可以在保持与JavaScript的兼容性的同时,享受到更加严谨的类型检查和更丰富的编程模式。 2. TypeScript与JavaScript的关系:尽管TypeScript在JavaScript的基础上增加了新的特性,但它...

              基于ssm+vue的少儿编程网上报名系统源码数据库.zip

              2. **课程展示**:展示各种编程课程,包括课程介绍、师资力量、课时安排等详细信息。 3. **报名功能**:用户可以选择感兴趣的课程进行在线报名,系统会自动检查库存并完成支付接口对接。 4. **订单管理**:用户...

              前端开源库-purescript-installer

              4. **互操作性**: 由于Purescript与JavaScript高度兼容,可以方便地调用JavaScript库,同时JavaScript也可以调用Purescript编写的模块。 5. **活跃社区**: Purescript拥有一个积极的社区,不断更新和维护库,提供了...

              禁用屏幕保护程序和自动挂起_JavaScript_下载.zip

              在这个场景中,我们关注的是JavaScript编程语言如何与操作系统交互,来实现这样的功能。虽然"gnome-shell-extension-caffeine-master"这个文件名暗示了这是针对GNOME桌面环境的一个扩展,我们将先讨论JavaScript的...

              Espruino_SGP30_module:Espruino模块可与GY-SGP30交互

              Espruino是一款基于JavaScript的嵌入式编程平台,使得硬件控制变得简单易行,而无需复杂的嵌入式编程知识。 GY-SGP30传感器是夏普公司生产的一款环境空气质量监测设备,主要用于检测室内空气质量中的挥发性有机化合...

              学生管理系统

              《学生管理系统:基于JSP MVC模式的实现与详解》 在信息技术日新月异的今天,各类管理系统已经广泛应用于各个领域。其中,学生管理系统作为教育信息化的重要组成部分,它旨在高效、便捷地管理学生的个人信息、成绩...

              simple-events:JavaScript 对象的简单事件扩展

              在JavaScript编程中,事件处理是构建交互式网页和应用程序的核心组成部分。"simple-events"是一个针对JavaScript对象的轻量级事件扩展库,它提供了一种简洁的方式来实现发布/订阅(publish/subscribe)模式,使得...

              米奇.zip网站源码ECSHOP网站源码打包下载

              2. MVC模式:ECSHOP遵循Model-View-Controller(模型-视图-控制器)设计模式,使代码结构清晰,易于维护和扩展。 3. HTML/CSS/JavaScript:前端界面使用HTML、CSS和JavaScript构建,实现动态交互效果,提升用户体验...

              JavaScriptix - OO Javascript Repository-开源

              总的来说,JavaScriptix 是一个专注于 JavaScript 面向对象编程的开源资源库,提供了模块化的类库和良好的文档支持。它鼓励开发者遵循面向对象的原则进行编码,利用开源社区的力量改进和扩展代码。对于想要利用 ...

            Global site tag (gtag.js) - Google Analytics