JavaScrip模块模式

306 阅读3分钟

这是我参与8月更文挑战的第11天,活动详情查看:8月更文挑战

最近这些年模块化一直是热点话题,我们想要了解模块化必须先了解私有变量和私有函数。我们先说一下私有变量。

私有变量

任何定义在函数块中的变量,都可以认为是私有的,因为这个函数或者块的外部无法访问其中的变量。私有变量包括函数参数,局部变量,以及函数内部定义的其他函数。

    function add(x,y){
        let sum = x + y;
        return sum;
    }

这里的sum和x,y都是私有变量,这几个变量只能在函数内部使用,不能在函数外部访问。如果这个函数创建了一个闭包,则这个闭包可以通过作用域链访问外部的这三个变量,这样就能创建出访问私有变量的公共方法。

特权方法

特权方法是能够访问函数私有变量及私有函数的共有方法。

    function Person(name) {
        this.getName = function () {
            return name;
        };
        this.setName = function (value) {
            name = value;
        };
    }
    let person = new Person('jackson');
    console.log(person.getName()); // 'jackson' 
    person.setName('bear');
    console.log(person.getName()); // 'bear' 

这段代码中定义了俩个特权方法getname和setname,每个方法都可以构造函数外部调用,并通过它们来读写私有的name变量。但是这种方法是每个实例都会重新创建一遍新方法,我们可以用静态私有变量来避免这个问题。

静态私有变量

特权方法也可以通过使用私有作用域定义私有变量和函数来实现

      (function () {
        // 私有变量和私有函数
        let sum = 1;

        function private() {
            return false;
        }
        // 构造函数
        MyObject = function () {};
        // 公有和特权方法
        MyObject.prototype.publicMethod = function () {
            sum++;
            return private();
        };
    })();

这里匿名函数表达式创建了一个包含构造函数及其他方法的私有作用域,首先定义的是私有变量和私有函数,任何定义了构造函数和共有方法。公有方法定义在构造函数的原型上,这个和典型的原型模式差不多。

模块模式

模块模式是在单例对象基础上加以扩展,使其通过作用域链来关联私有变量和特权方法。 单例是通过字面量来创建的。单例对象就是只有一个实例对象,以下就是单例的例子。

    let singleton = {
        name: value,
        method() {
            // 方法的代码
        }
    };

在模块模式中,单例对象作为一个模块,经过初始化可以包含某些私有的数据,而这些数据又可以通过其暴露的公共方法来访问。以这种方式创建的每个单例对象都是 Object 的实例,因为最终单例都由一个对象字面量来表示。不过这无关紧要,因为单例对象通常是可以全局访问的,而不是作为参数传给函数的。模块模式的样板代码如下。

    let application = function () {
        // 私有变量和私有函数 
        let components = new Array();
        // 初始化
        components.push(new BaseComponent());
        // 公共接口
        return {
            getComponentCount() {
                return components.length;
            },
            registerComponent(component) {
                if (typeof component == 'object') {
                    components.push(component);
                }
            }
        };
    }();

模块增强模式

如果遇到单例对象需要某一个特定类型的实例,但又必须给它添加额外属性或者方法的场景我们可以选择模块增强模式。

    let singleton = function () {
        // 私有变量和私有函数
        let privateVariable = 10;

        function privateFunction() {
            return false;
        }
        // 创建对象
        let object = new CustomType();
        // 添加特权/公有属性和方法
        object.publicProperty = true;
        object.publicMethod = function () {
            privateVariable++;
            return privateFunction();
        };
        // 返回对象
        return object;
    }();