xml地图|网站地图|网站标签 [设为首页] [加入收藏]

软件资讯

当前位置:美高梅游戏网站 > 软件资讯 > JavaScript模块模式

JavaScript模块模式

来源:http://www.gd-chuangmei.com 作者:美高梅游戏网站 时间:2019-09-03 19:56

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

转自:http://www.oschina.net/translate/javascript-module-pattern-in-depth

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

  • 定义一个模块

    var Module = (function(){
    var my = {}, //在末尾暴露出去的对象
    privateVariable = 1; //模块内部私有变量
    function privateMethod (){ //私有方法
    //...
    };

      my.modulePrototype = 1;         //外部可调用的属性和方法
      my.moduleMethod = function(){
          //...
      };
    
      return my;                      //将my暴露出去
    })()
    

匿名闭包

注意,我们声明了一个全局模块MODULE,有两个公开属性:方法MODULE.moduleMethod和属性MODULE.moduleProperty。而且,匿名函数的闭包还维持了私有内部状态。同时学会之上的内容,我们就很容易引入需要的全局变量,和输出到全局变量。
通过将匿名自执行函数的返回值赋给一个新的变量来将匿名函数内的方法和属性暴露出来,通过Module.modulePrototype,可Module.moduleMethod()来调用。

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

  • 扩展模块
    首先我们在扩充模块的文件内先引入模块(全局),给他添加属性,然后再输出他:

    var Module = (function(my){
      my.anotherMethod = function(){
          //给my添加一个方法
      };
    
      return my;
    })(Module)//将Module作为参数传入这个匿名自执行函数,给他添加一个新的方法之后再将my返回重新赋值给Module,注意前面的var,加不加无所谓
    
  • 松耦合扩充
    上面的例子有个不好的地方就是我们在扩充模块时,这个模块必须是已存在的,这样我们就必须在模块加载完成之后才可以给他添加一些方法。这样我们就无法做到异步加载,因此我们可以创建灵活多部分的模块,可以将他们无顺序加载,以松耦合扩充。每个文件应有如下的结构:
    var Module = (function(my){
    my.anotherMethod = function(){
    //给my添加一个方法
    };

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

这个模式里,var语句是必须的,以标记引入时不存在会创建。这意味着我们可以同时加载所有模块文件而不被阻塞。

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

  • 紧耦合扩充
    虽然松耦合可以异步加载,但是也会有一些劣势,最重要的,我们不能安全的覆盖模块属性(因为没有加载顺序)。紧耦合扩充意味着一组加载顺序,但是允许写覆盖:
    var Module = (function (my)
    {
    var old_moduleMethod = my.moduleMethod;
    my.moduleMethod = function(){
    //method override,has access to old through old_moduleMethod
    }

      return my;
    })(Module)
    
  • 克隆和继承
    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.module_NewMethod = function(){           //添加新方法
          //override method on the clone,access to super through super_moduleMethod
      };
    
      return my;
    })(Module);
    

引用全局变量

这种方式也许最不灵活。他可以实现巧妙的组合,但是牺牲了灵活性。正如我写的,对象的属性或方法不是拷贝,而是一个对象的两个引用。修改一个会影响其他。这可能可以保持递归克隆对象的属性固定,但无法固定方法,除了带eval的方法。不过,我已经完整的包含了模块。(其实就是做了一次浅拷贝)。

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;   }());  

本文由美高梅游戏网站发布于软件资讯,转载请注明出处:JavaScript模块模式

关键词:

上一篇:没有了

下一篇:没有了