Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

深入JavaScript(2):全面解析Module模式 #113

Open
HuYuee opened this issue Aug 21, 2016 · 0 comments
Open

深入JavaScript(2):全面解析Module模式 #113

HuYuee opened this issue Aug 21, 2016 · 0 comments

Comments

@HuYuee
Copy link
Contributor

HuYuee commented Aug 21, 2016

简介

首先我们来看看Module模式的基本特征:

1、模块化,可重用
2、封装了变量和function,和全局的namaspace不接触,松耦合
3、只暴露可用public的方法,其它私有方法全部隐藏

关于Module模式,最早是由YUI的成员Eric Miraglia在4年前提出了这个概念,我们将从一个简单的例子来解释一下基本的用法(如果你已经非常熟悉了,请忽略这一节)。

基本用法

先看一个最简单的例子:

var Calculator = function (eq) {
    //这里可以声明私有成员
    var name = "huyue";

    return {
        // 暴露公开的成员
        add: function () {
                console.log(name);
        }
    };
};

匿名闭包

匿名闭包是让一切成为可能的基础,而这也是JavaScript最好的特性,我们来创建一个最简单的闭包函数,函数内部的代码一直存在于闭包内,在整个运行周期内,该闭包都保证了内部的代码处于私有状态。

(function () {
    // ... 所有的变量和function都在这里声明,并且作用域也只能在这个匿名闭包里
    // ...但是这里的代码依然可以访问外部全局的对象
}());

注意,匿名函数后面的括号,这是JavaScript语言所要求的,因为如果你不声明的话,JavaScript解释器默认是声明一个function函数,有括号,就是创建一个函数表达式,也就是自执行,用的时候不用和上面那样在new了,当然你也可以这样来声明:

(function () {/* 内部代码 */})();

引用全局变量

JavaScript有一个特性叫做隐式全局变量,不管一个变量有没有用过,JavaScript解释器反向遍历作用域链来查找整个变量的var声明,如果没有找到var,解释器则假定该变量是全局变量,如果该变量用于了赋值操作的话,之前如果不存在的话,解释器则会自动创建它,这就是说在匿名闭包里使用或创建全局变量非常容易,不过比较困难的是,代码比较难管理,尤其是阅读代码的人看着很多区分哪些变量是全局的,哪些是局部的。
好在在匿名函数里我们可以提供一个比较简单的替代方案,我们可以将全局变量当成一个参数传入到匿名函数然后使用,相比隐式全局变量,它又清晰又快,我们来看一个例子:

(function ($) {
    // 这里,我们的代码就可以使用全局的jQuery对象了
} (jQuery));

不过,有时候可能不仅仅要使用全局变量,而是也想声明全局变量,如何做呢?我们可以通过匿名函数的返回值来返回这个全局变量,这也就是一个基本的Module模式,来看一个完整的代码:

var blogModule = (function () {
    var my = {}, privateName = "博客园";

    function privateAddTopic(data) {
        // 这里是内部处理代码
    }

    my.Name = privateName;
    my.AddTopic = function (data) {
        privateAddTopic(data);
    };

    return my;
} ());

子模块

最后一个也是最简单的使用方式,那就是创建子模块

//parent.js   父文件
parent = (function(){
   //父模块的内容
}());
//son.js   子文件
parent.son = (function () {
    //子模块的内容
} ());
@HuYuee HuYuee assigned HuYuee and unassigned HuYuee Aug 22, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant