全面解析Module模式 复习


基本用法

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

    var eqCtl = document.getElementById(eq);

    return {
        // 暴露公开的成员
        add: function (x, y) {
            var val = x + y;
            eqCtl.innerHTML = val;
        }
    };
};

每次调用的时候new一下,不过这样每个实例都独立存在于内存中

var calculator = new Calculator('eq');
calculator.add(2, 2);

1、匿名闭包

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

之前说过()内的function属于函数表达式,可以执行。

2、全局变量在模块中的使用

  • 全局变量传入模块中
    全局变量可以作为参数传入匿名函数中
function ($, YAHOO) {
    // 这里,我们的代码就可以使用全局的jQuery对象了,YAHOO也是一样
} (jQuery, YAHOO));
  • 模块中声明全局变量
var blogModule = (function () {
    var my = {}, privateName = "博客园";

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

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

    return my;
} ());

高级用法

1、松耦合扩展

Module模式的一个限制就是所有的代码都要写在一个文件,但是在一些大型项目里,将一个功能分离成多个文件是非常重要的,因为可以多人合作易于开发。再回头看看上面的全局参数导入例子,我们>能否把blogModule自身传进去呢?答案是肯定的,我们先将blogModule传进去,添加一个函数属性,然后再返回就达到了我们所说的目的。

 var blogModule = (function (my) {

    // 添加一些功能   

    return my;
} (blogModule || {}));  

每个文件都保证这个结构,我们就能任意顺序加载文件。注意:var声明必须存在


2、跨文件共享私有对象

让模块中不同问价可以相互访问私有对象。

var blogModule = (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;
        };

    return my;
} (blogModule || {}));

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


感谢@汤姆大叔 的《深入理解JavaScript系列》指导我学习!



blog comments powered by Disqus

Published

12 February 2014

Category

Tags