这两种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变量的访问。
这两种变体会产生完全相同的对象吗?
答案 0 :(得分:2)
他们在功能上并没有什么不同。 MODULE
对象将以相同的方式工作,但第一个是首选,因为语法更清晰。无需new
和this
。
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();
}());
var module = (function () {
return {...};
}());
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
变量而不是共享静态变量。