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

【转】JavaScript闭包和模块模式

 
阅读更多

 

原文:http://www.joezimjs.com/javascript/javascript-closures-and-the-module-pattern/

在JavaScript中一个最广泛使用的设计模式是模块的模式。模块模式使用了JavaScript中的一个很棒的特性-闭包- 用来给你方法中的隐私一些控制这样的第三方应用程序不能访问私有数据或覆盖它。在这篇文章中,我会教你什么是闭包,它是如何工作的,以及如何利用它在你的JavaScript代码中实现模块模式。
什么是闭包?
闭包是JavaScript语言的一种构造。在JavaScript内所有变量都能在全局范围内访问,除非变量在函数内用var关键字声明过。

variable1 = 1; //全局范围
var variable2 = 2; // 不在一个函数内: 全局范围
      
function funcName() {
  variable3 = 3; // 没用var关键字声明: 全局范围
  var variable4 = 4; //仅本地访问
}
 




view raw gistfile1.js This Gist brought to you by GitHub.
在一个函数内,你也可以获得全局范围和每个你所在的函数上级范围的访问权限。换句话说,函数内声明变量只能在函数包围范围内访问。

var globalvar = 1; //全局范围

function outer() {
  var outervar = 2; // outer()范围内

  function inner() {
    var innervar = 3; // inner()范围内
    console.log(globalvar); // => 1
    console.log(outervar); // => 2
    console.log(innervar); // => 3
  }

  console.log(globalvar); // => 1
  console.log(outervar); // => 2
  console.log(innervar); // => Reference Error引用错误;
}

console.log(globalvar); // => 1
console.log(outervar); // => Reference Error引用错误
console.log(innervar); // => Reference Error引用错误
 


每一个真正的JavaScript程序员应该知道这一点,除非他不思进取。知道这一点,你可以得出这样的结论,用一种办法来保持你所有代码在全局命名空间外,是正确的。这特别有用,当你不想给任何人在未经许可的情况下有重写你任何代码的机会。你可以通过使用一个匿名函数(不给它命名,没有被赋予一个变量)立即执行自身。这是众所周知的自调用匿名函数(SIAF),虽然它可能是更准确地称为立即调用的函数表达 (IIFE–读做“iffy”) -作者Ben Alman。

(function() {
    // 这函数立即执行,内部所有变量都是私有的
}());
 



view raw gistfile1.js This Gist brought to you by GitHub.
紧接着右大括号,是左右括号于是函数将立即执行。围绕整个函数表达式的括号不是运行的代码必需的,但一般用作给其他开发人员的信号,这是一个IIFE,而不是一个标准函数。有些人喜欢在前面加上一个惊叹号(!)或分号(;),而不是用括号包起来。
用闭包的模块模式
知道了闭包是什么,我们就可以使用模块模式创建对象。通过返回一个对象或变量并赋给一个函数外变量,这样我们可以暴露任何希望暴露给外界的,我们可以有公开和私有的方法。

var Module = (function() {
    // 下面函数是私有的,但可以被公开函数访问
    function privateFunc() { … };
  
    // 返回一个对象赋予Module
    return {
        publicFunc: function() {
            privateFunc(); // publicFunc可以直接访问privateFunc
        }
    };
}());
 


这就是模块模式的本质。您还可以使用参数传入或缩写常用资源的名称:

var Module = (function($, w, undefined) {
    // …
    // return {…};
}(jQuery, window));
 


我传入jQuery和window,被分别缩写为$和w。注意我没有传任何东西作为第三个参数。这样参数undefined将是undefined,所以它完美地工作。有些人这样处理undefined是因为无论如何,它是可编辑的。所以,如果你判断某某是否是undefined,但undefined可能已经改变,你的比较将不起作用。这种技术保证它将按预期工作。
透露模块模式revealing module pattern
透露模块模式是另一种方式来写模块模式,需要更多点代码,但有时更容易理解和阅读。不同于在IIFE中定义所有私有变量并在返回对象中定义公开方法,你把所有方法都写在IIFE中,只是“透露”哪些是你想公开在return语句内的。

var Module = (function() {
    // 现在所有函数直接互访
    var privateFunc = function() {
        publicFunc1();
    };
  
    var publicFunc1 = function() {
        publicFunc2();
    };
  
    var publicFunc2 = function() {
        privateFunc();
    };
  
    // 返回对象赋予Module
    return {
        publicFunc1: publicFunc1,
        publicFunc2: publicFunc2
    };
}());
 


对比正常的模块模式,透露模块模式有几个优点:

    所有函数的声明和实现都在同一个地方,从而制造较少的混乱。
    私有函数现在可以访问公开函数,如果他们需要。
    当一个公开函数需要调用另一个公开函数时,他们调用publicFunc2(),而不是用this.publicFunc2(),从而节省了几个字符。

透露模块模式的唯一真正的缺点,正如我所说,是你必须写更多的代码,因为你必须先写好函数然后再把它的名字写在return语句内,尽管它最终可能会因为你可以忽略this.部分而节省你的代码。
扩展模块模式
我想谈的最后一件事是使用模块模式扩展已经存在的模块。这很常用,当为jQuery之类的库做插件,如下。

var jQuery = (function($) {
    $.pluginFunc = function() {
        …
    }
  
    return $;
}(jQuery));

 

此代码是相当灵活的,因为你甚至不需要var jQuery=或接近尾部的return语句。没有它们jQuery仍将可以用这个新方法扩展。实际上返回和赋值整个jQuery对象,可能在性能上有损失,但是,如果你想在扩展jQuery的同时,分配jQuery到一个新的变量名,你只需改变第一行的jQuery为任何你想要的。
结论
朋友们,今天就到这里。这些都是常见的技术和功能,即使你不使用这篇文章的知识,保留在你的脑海,以防万一用到(很可能会发生)。。。最后,不要忘记分享和在下面评论。感谢和编码快乐!

分享到:
评论

相关推荐

    JavaScript利用闭包实现模块化

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

    javascript闭包高级教程

    ### JavaScript闭包高级教程 #### 简介 在JavaScript编程中,“闭包”是一个非常重要的概念,尤其对于希望深入理解和高效使用JavaScript的开发者来说。简单地说,闭包是一种能够记住并访问其创建时周围环境的函数...

    揭开Javascript闭包的真实面目

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

    JavaScript闭包详解1

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

    JavaScript闭包的定义和理解,含代码示例

    ### JavaScript闭包详解 #### 一、闭包的定义与概念 闭包是JavaScript中一个非常重要的概念,它涉及到函数作用域以及变量的作用域链。简单来说,闭包就是一个能够访问其外部作用域中变量的函数。具体而言,当一个...

    JavaScript闭包

    JavaScript闭包是编程语言中的一个核心概念,...总之,JavaScript闭包是实现复杂功能的关键工具,理解和掌握闭包对于提高编程效率和代码质量具有重要意义。在实际开发中,灵活运用闭包可以写出更加高效、优雅的代码。

    JavaScript设计模式+JavaScript模式+JavaScript异步编程

    设计模式和异步编程是提升JavaScript代码质量和效率的关键。以下将详细介绍这三本书所涵盖的知识点: 1. **JavaScript设计模式**: 设计模式是软件工程中经过实践验证的、解决常见问题的有效方法。在JavaScript中...

    闭包javascript.pdf

    描述:详细描述JavaScript闭包,适合更进一步了解闭包。 标签:javascript 闭包 从给定的文件信息来看,主要围绕JavaScript中的闭包概念进行深入探讨。闭包是计算机科学中一个重要的概念,特别是在函数式编程语言...

    javascript闭包真经

    模块模式可以帮助我们封装相关的变量和函数,避免全局污染。 ```javascript var module = (function () { var privateData = 'I am private'; function privateMethod() { console.log('This is a private ...

    JavaScript高级与设计模式.zip

    5. **模块模式(Module)**:JavaScript中,可以利用闭包来创建私有作用域,保护内部变量和方法,只暴露必要的接口。这有助于代码组织和防止命名冲突。 6. **策略模式(Strategy)**:定义了一系列的算法,并将每个...

    精通javascript设计模式en版pdf

    **模块模式**是JavaScript中解决命名冲突和封装的一种策略。通过闭包,模块模式可以隐藏内部状态,同时暴露公共接口。书中还讲解了如何结合模块模式与立即执行函数表达式(IIFE)来创建独立的执行环境。 **装饰器...

    学用JavaScript设计模式

    在编程领域,设计模式主要有三大类:创建型模式、结构型模式和行为型模式。创建型模式关注对象的创建过程,提供了一种在创建对象的同时隐藏创建逻辑的方式,而不是使用new直接实例化对象。常见的创建型模式有工厂...

    详谈JavaScript的闭包及应用

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

    27 模块模式.pdf

    JavaScript设计模式精讲中,模块模式是一个核心概念,它对于构建可维护、可扩展的代码至关重要。...通过合理运用命名空间模式、模块模式和揭示模块模式,开发者可以创建出高效、可维护的JavaScript应用程序。

    Javascript 设计模式 很经典 第一本

    在JavaScript中,可以通过闭包、模块模式等方式实现单例。 3. **观察者模式**:定义了一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。适用于事件处理机制。 4. **...

    js闭包个人理解

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

    【JavaScript源代码】js闭包和垃圾回收机制示例详解.docx

    ### JavaScript闭包与垃圾回收机制详解 #### 一、闭包 ##### 1.1 闭包是什么? 闭包(Closure)是JavaScript中一个非常重要的概念,它涉及到函数及其相关的词法作用域。简单来说,闭包就是能够访问其自身作用域...

    Javascript的一种模块模式

    模块模式的核心思想是利用JavaScript的闭包特性来保护内部变量和方法,防止外部直接访问。 首先,创建一个命名空间对象是为了避免全局变量污染和命名冲突。在示例中,使用YUI库的`YAHOO.namespace()`方法创建了一个...

    Javascript模块化编程详解

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

    JavaScript中闭包之浅析解读(必看篇)

    3. 实现模块化开发:在JavaScript中,可以通过闭包来创建模块化的代码。每个模块都可以有自己的私有变量和公共方法,而外部只通过模块暴露的接口进行通信,这种方式可以大大增强代码的封装性和可维护性。 4. 减少...

Global site tag (gtag.js) - Google Analytics