`
deng131
  • 浏览: 677740 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

JavaScript模块模式(闭包)

阅读更多
什么是闭包?“官方”的解释是:闭包是一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。闭包的两个特点:
1、作为一个函数变量的一个引用 - 当函数返回时,其处于激活状态。
2、一个闭包就是当一个函数返回时,一个没有释放资源的栈区。

全局变量是魔鬼。在YUI中,我们仅用两个全局变量:YAHOO和YAHOO_config。YUI的一切都是使用YAHOO对象级的成员或这个成员作用域内的变量。我们建议在你的应用程序也使用类似的规则。

Douglas Crockford已经传授了一个有用的单例模式(singleton pattern)实现此规则,我认为他的模式有益于你基于YUI的那些应用。Douglas叫它模块模式(module pattern)。它是如下工作的:

   1. 创建一个命名空间对象:如果你使用YUI,可以用YAHOO.namespace()方法: YAHOO.namespace("myProject");这分配了一个空的myProject对象,是YAHOO的一个成员(如 果myProject已存在的话,则不会被覆盖)。现在我们可以开始添加YAHOO.myProject的成员。
   2. 对你的命名空间对象分配一个匿名函数返回值:

      YAHOO.myProject.myModule = function () {
      return  {
        myPublicProperty: "我作为YAHOO.myProject.myModule.myPublicProperty被访问。";
        myPublicMethod: function () {
          YAHOO.log("我作为YAHOO.myProject.myModule.myPublicMethod被访问。");
        }
      };
      }(); // 这个括号导致匿名函数被执行且返回

      注意有闭合大括号和紧接着的括号()的最后一行—这种符号导致了匿名函数的立即执行,返回包含myPublicProperty和 myPublicMethod的对象。只要这个匿名函数一返回,返回对象就作为YAHOO.myProject.myModule被访问。
   3. 在匿名函数中,在返回语句前加入“私有”方法和变量。到目前为止,我们只是将myPublicProperty和 myPublicMethod直接分配到YAHOO.myProject.myModule中。此外,当我们在返回语句之前放置一些代码时,这个模式还支持被增加的效用。

      YAHOO.myProject.myModule = function () {
      //“私有”变量:
      var myPrivateVar = "我仅能在YAHOO.myProject.myModule内被访问。";
      //私有方法:
      var myPrivateMethod = function () {
          YAHOO.log("我仅能在YAHOO.myProject.myModule内被访问。");
      }

      return  {
          myPublicProperty: "我作为YAHOO.myProject.myModule.myPublicProperty能被访问。"
          myPublicMethod: function () {
          YAHOO.log("我作为YAHOO.myProject.myModule.myPublicMethod能被访问。");
          //在myProject,我能访问私有的变量和方法
          YAHOO.log(myPrivateVar);
          YAHOO.log(myPrivateMethod());
          //myPublicMethod的原生作用域是myProject,我们可以用“this”来访问公共成员。
          YAHOO.log(this.myPublicProperty);
          }
      };
      }();

      在上面的代码中,我们从一个匿名函数返回有两个成员的一个对象。在YAHOO.myProject.myModule内部,可以分别用 this.myPublicProperty和this.myPublicMethod来访问。在YAHOO.myProject.myModule外部,公共成员可以用YAHOO.myProject.myModule.myPublicProperty和 YAHOO.myProject.myModule.myPublicMethod来访问。
      私有变量myPrivateProperty和 myPrivateMethod只能被匿名函数本身或返回对象的成员访问。尽管匿名函数会立即执行和终止,但它们依然是保留着,凭借闭包(closure)的力量——通过一个函数的局部变量在这个函数返回后是保留的规则。只要 YAHOO.myProject.myModule需要它们,我们的两个私有变量就不会被销毁。
   4. 实践这个模式。让我们来看看这个模式的一个常见应用案例。假设你有一个列表,列表上的一些项可以被拖拽。应用拖拽的项上有拖拽的CSS类。

      <!--这个脚本文件包含所有的YUI实用程序-->
        <script type="text/javascript"
      src="http://yui.yahooapis.com/2.2.2/build/utilities/utilities.js"></script>
      <ul id="myList">
         <li class="draggable">一项</li>
         <li>二项</li> <!--二项将不能被拖拽-->
         <li class="draggable">三项</li>
         </ul>
      <script>
        YAHOO.namespace("myProject");
        YAHOO.myProject.myModule = function () {
       //YUI实用程序的私有简写引用:
        var yue = YAHOO.util.Event,
        yud = YAHOO.util.Dom;
       //私有方法
        var getListItems = function () {
       // 注意这个地方使用其他的私有变量,包括"yud"YAHOO.util.Dom的简写:
        var elList = yud.get("myList");
        var aListItems = yud.getElementsByClassName(
        "draggable", //得到仅有CSS类"draggable"的项
        "li", //仅返回列表项
        elList //限定搜索改元素的子
        );
        return aListItems;
        };
       //这个放回的对象将变成YAHOO.myProject.myModule:
        return  {
       aDragObjects: [], //可对外访问的,存储DD对象
       init: function () {
        //直到DOM完全加载好,才实现列表项可拖拽:
        yue.onDOMReady(this.makeLIsDraggable, this, true);
        },
       makeLIsDraggable: function () {
        var aListItems = getListItems(); //我们可以拖拽的那些元素
        for (var i=0, j=aListItems.length; i<j; i++) {
        this.aDragObjects.push(new YAHOO.util.DD(aListItems[i]));
        }
        }
       };
        }();
      //上面的代码已经执行,所以我们能立即访问init方法:
        YAHOO.myProject.myModule.init();
        </script>

      这是一个简单的例子,特意写的详细一些——如果按照这种方式做,我们无疑能把它写的更紧凑。当项目变得更加复杂和它的API增加,这个模式缩放的很好。通过这种方式,它避免了全局命名空间,提供了对外的可以访问的API方法,支持受保护或“私有”的数据和方法。

    * [1]原文:《a javascript module pattern》。这是在YUI blog上的,有的地方可能打不开,可以搜一下英文的转载或者利用搜索引擎的缓存也能看。
    *
    * [2]《A JavaScript Module Pattern – JavaScript的一种模组模式》这是别人的翻译,参考了不少,不过感觉挺不方便看的,这是我翻译的这篇文章的一个原因,当然最主要的原因是这篇文章算是学习YUI的最基础的文章了,整个YUI的模块模式都基于此。

分享到:
评论

相关推荐

    JAVASCRIPT设计模式[收集].pdf

    闭包的常见用法包括工厂函数和模块模式等,这些都是实现封装和避免全局作用域污染的有效方式。然而,闭包的过度使用可能会导致内存泄漏,因为它会使得函数内部使用的变量无法被垃圾回收机制清除。因此,在使用闭包时...

    Javascript模块模式分析

    总之,JavaScript模块模式通过创建命名空间和利用闭包,提供了在JavaScript中实现封装和信息隐藏的有效方式。它有助于构建可维护的、模块化的代码,从而改善代码质量和可扩展性。在实际开发中,可以结合其他设计模式...

    闭包javascript.pdf

    2. **模块模式**:使用闭包可以实现模块化编程,通过返回一个对象来暴露公共方法,同时隐藏内部实现细节。 3. **事件处理**:在事件驱动的编程模型中,闭包使得我们可以在事件发生时访问到事件触发时的上下文状态。 ...

    Javascript模块化编程详解

    总的来说,JavaScript模块化编程是一个重要的实践领域,通过合理使用匿名闭包、全局变量导入和模块导出来组织代码,可以提高代码的可读性和可维护性。随着语言特性的演进,开发者有更多选择来适应不同的项目需求。

    JavaScript利用闭包实现模块化

    此外,JavaScript的模块化还支持单例模式,即整个应用程序只存在一个模块实例。在示例中,通过立即调用`CoolModule`并将其结果赋值给`foo`,就创建了一个单例模块。这样,每次尝试访问或修改`foo`时,都只会操作同一...

    JavaScript闭包详解1

    总的来说,闭包是JavaScript中强大且灵活的工具,用于实现封装、数据隐私以及模块化等高级编程模式。尽管使用时需谨慎,以防止内存问题,但正确掌握和利用闭包,能够显著提高代码质量及可维护性。

    Javascript 设计模式系统讲解与应用视频资源地址.7z

    模块模式是JavaScript中实现封装和私有变量的一种方式。通过立即执行函数表达式(IIFE)和闭包,可以在全局作用域中创建独立的命名空间,防止变量污染。 六、观察者模式 观察者模式是一种行为设计模式,它定义了...

    24_JavaScript模块化1

    在JavaScript中,有多种方式来实现模块化,例如使用闭包、命名空间、模块模式等。其中,模块模式是最常用的模块化方式,它可以将代码组织成一个个小的模块,每个模块都可以导出自己的变量、函数、对象等。 抛出异常...

    javascript闭包高级教程

    这种能力使得闭包能够在函数执行完毕后依然保留对外部作用域中的变量的访问权,这对于实现诸如私有变量、模块模式等功能至关重要。 #### 对象属性名解析 在深入了解闭包之前,有必要先了解JavaScript中对象属性是...

    JavaScriptModulePatterns:JavaScript模块模式

    JavaScript模块模式 然后,Node.js模块系统允许模块导出任何值,无论是字符串,数字,单个函数还是更复杂的对象。 让我们来看一些可能出现的常见模式: 一种功能 单例对象 基于封闭的类 基于原型的类 外墙模块 ...

    JavaScript模式(中文版带目录)

    这部分可能介绍了一些常见的对象创建模式,如工厂函数、构造函数模式、模块模式、单例模式等。这些模式有助于在不同的场景下创建和管理对象实例,提高代码的组织性和可扩展性。 六、代码复用模式 代码复用是软件...

    JavaScript闭包

    这种特性使得闭包在JavaScript中被广泛用于数据封装、模块化、异步操作以及性能优化等方面。 首先,我们要理解JavaScript的作用域链。每个函数在创建时,都会形成一个作用域链,这个链由当前执行环境和所有父级执行...

    揭开Javascript闭包的真实面目

    【JavaScript 闭包详解】 闭包是JavaScript编程中一个核心且...理解闭包对于深入掌握JavaScript至关重要,因为它在许多高级编程技巧和模式中扮演着重要角色。通过实践和研究,初学者将逐渐领悟闭包的魅力和实用性。

    详谈JavaScript的闭包及应用

    3. 实现模块模式,控制模块内部的变量和方法的可见性。 4. 在异步编程中,特别是在处理回调函数时,闭包能够保持当前的上下文,这样即使在异步操作完成后,也能够访问到相应的变量。 在文中的示例代码中,创建了一...

    JavaScript设计模式与开发实践_himppf_js_jspremise_精通javascript_Js设计模式_

    在JavaScript中,"模块模式"是常见的设计模式,它通过闭包来封装变量和函数,防止全局污染。"工厂模式"可以用来动态地创建具有相似特征的对象,而"单例模式"确保一个类只有一个实例,常用于管理共享资源。"装饰器...

    27 模块模式.pdf

    JavaScript设计模式精讲中,模块模式是一个核心概念,它对于构建可维护、可扩展的代码至关重要。模块模式有助于保持代码的组织性和隔离性,避免命名冲突,并提供一定程度的数据封装和安全。 1. **命名空间模式**: ...

    javascript闭包真经

    闭包也可以用来实现模块模式,这是一种常见的组织代码的方式。模块模式可以帮助我们封装相关的变量和函数,避免全局污染。 ```javascript var module = (function () { var privateData = 'I am private'; ...

    js闭包个人理解

    2. **模块模式**:在构建大型项目时,使用闭包来模拟模块化编程,避免全局命名冲突。 3. **事件处理程序**:在DOM操作中,闭包经常被用来捕获事件处理程序中的当前状态。 #### 注意事项 虽然闭包提供了强大的功能...

    Javascript 设计模式系统讲解与应用

    模块模式 - **定义**:通过组合使用立即执行函数表达式(IIFE)和闭包,实现代码封装和私有变量的保护。 - **应用场景**:适用于需要封装内部状态和方法的场景,如实现复杂的组件或功能模块。 - **实现方式**:使用...

Global site tag (gtag.js) - Google Analytics