这两种模块模式之间的差异

时间:2012-06-26 13:58:59

标签: javascript

这两种JavaScript模块模式之间的功能是否存在差异?

var MODULE = (function() {

    var privvy = "I'm private!";

    return {
        getPublic: function() {
            return "I'm public";
        },      
        getPriv: function() {
            return privvy;
        }       
    };
}());

var MODULE = (function() {

    var privvy = "I'm private!";

    return new function() {
        this.getPublic = function() {
            return "I'm public";
        };
        this.getPriv = function() {
            return privvy;
        };
    };
}());

我认为发生的事情是,首先,一个具有两个公共成员的对象被显式声明然后返回。其中一个成员有一个函数作为一个值,它引用了'private'变量(即闭包由立即执行的函数形成,但getPublic()方法在此函数完成执行后仍然可以访问此变量 - 我认为)

在第二个中,通过匿名构造函数创建一个对象,该构造函数将两个函数分配给可公开访问的变量,IEF创建闭包,以同样的方式限制对priv变量的访问。

这两种变体会产生完全相同的对象吗?

3 个答案:

答案 0 :(得分:2)

他们在功能上并没有什么不同。 MODULE对象将以相同的方式工作,但第一个是首选,因为语法更清晰。无需newthis

JSLint证实了这一点。对于第二种模式,它抱怨return new function() {是一种“奇怪的结构”。

编辑:正如@zzzzBov和@Bergi指出的那样,对象的原型存在差异。请查看他们的答案以获得详细说明。

答案 1 :(得分:2)

两个版本的情况略有不同。作为参考,我添加了基本格式的简单示例(版本A & 版本B )。功能上没有显着差异,但版本B 增加了额外的范围:

var foo; //global scope
var module = (function () {
    var foo; //module scope
    return new function () {
        var foo; //inner scope
    };
}());

此外,在版本A 中返回的对象的原型将是Object.prototype,而在版本B 中,原型将是匿名函数的原型。< / p>

checking the module's __proto__ property against Object.prototype可以看到这种差异。


版本A 基本上是:

的简写
var module = (function () {
    var temp;
    temp = new Object();
    temp.foo = function () {...};
    return temp;
}());

版本B 基本上是:

的简写
var module = (function () {
    function anon() {
        this.foo = function () {...};
    }
    return new anon();
}());

版本A

var module = (function () {
    return {...};
}());

版本B

var module = (function () {
    return new function () {...};
}());

答案 2 :(得分:2)

结果没有太大区别,除了第二个例子中的对象有一个(不可数)原型属性“constructor”指向该匿名函数。这意味着,您可以使用new MODULE.constructor创建一份副本。

创建单例对象时,首选语法。第二个示例通常在没有new关键字的情况下使用,将构造函数返回为MODULE,以便您可以创建它的实例,可以访问所有相同(“静态”)priv变量

你可以使用类似的结果投入另一种模式:

var MODULE = new function() {
    var priv = "I'm private!";
    this.getPublic = function() {
        return "I'm public";
    };
    this.getPriv = function() {
        return priv;
    };
}();

它的行为更像你的第一个例子,但泄漏了一个构造函数,它创建了新的priv变量而不是共享静态变量。