我正在维护一些遗留代码,并注意到使用了以下定义对象的模式:
var MyObject = {};
(function (root) {
root.myFunction = function (foo) {
//do something
};
})(MyObject);
这样做有什么目的吗?它是否等同于只执行以下操作?
var MyObject = {
myFunction : function (foo) {
//do something
};
};
我并不打算按照自己的喜好去重构整个代码库,但我真的很想了解这种拐弯抹角的定义对象方式背后的原因。
谢谢!
发布于 2014-11-07 04:05:29
它被称为模块模式http://toddmotto.com/mastering-the-module-pattern/
主要原因是您需要创建真正私有的方法和变量。在您的例子中,它没有任何意义,因为它没有隐藏任何实现细节。
这里有一个使用模块模式有意义的例子。
var MyNameSpace = {};
(function(ns){
// The value variable is hidden from the outside world
var value = 0;
// So is this function
function adder(num) {
return num + 1;
}
ns.getNext = function () {
return value = adder(value);
}
})(MyNameSpace);
var id = MyNameSpace.getNext(); // 1
var otherId = MyNameSpace.getNext(); // 2
var otherId = MyNameSpace.getNext(); // 3
而如果你仅仅使用一个普通的对象,adder
和value
就会变成公共的
var MyNameSpace = {
value: 0,
adder: function(num) {
return num + 1;
},
getNext: function() {
return this.value = this.adder(this.value);
}
}
你可以通过做像这样的事情来打破它
MyNameSpace.getNext(); // 1
MyNameSpace.value = 0;
MyNameSpace.getNext(); // 1 again
delete MyNameSpace.adder;
MyNameSpace.getNext(); // error undefined is not a function
而是使用模块版本
MyNameSpace.getNext(); // 1
// Is not affecting the internal value, it's creating a new property
MyNameSpace.value = 0;
MyNameSpace.getNext(); // 2, yessss
// Is not deleting anything
delete MyNameSpace.adder;
MyNameSpace.getNext(); // no problemo, outputs 3
发布于 2014-11-07 04:24:08
在您所展示的特定情况下,在功能或可见性方面没有任何有意义的区别。
最初的程序员很可能采用这种方法作为一种模板,允许他定义私有变量,这些变量可以在定义myFunction
之类的东西时使用
var MyObject = {};
(function(root) {
var seconds_per_day = 24 * 60 * 60; // <-- private variable
root.myFunction = function(foo) {
return seconds_per_day;
};
})(MyObject);
这避免了每次调用函数时都计算seconds_per_day
,同时也避免了它污染全局作用域。
然而,这并没有什么本质上的区别,只是说
var MyObject = function() {
var seconds_per_day = 24 * 60 * 60;
return {
myFunction: function(foo) {
return seconds_per_day;
}
};
}();
原始编码器可能更希望能够使用root.myFunction = function
的声明性语法而不是myFunction: function
的对象/属性语法向对象添加函数。但这种差异主要是偏好问题。
然而,原始编码器采用的结构有一个优点,即可以很容易地在代码中的其他地方添加属性/方法:
var MyObject = {};
(function(root) {
var seconds_per_day = 24 * 60 * 60;
root.myFunction = function(foo) {
return seconds_per_day;
};
})(MyObject);
(function(root) {
var another_private_variable = Math.pi;
root.myFunction2 = function(bar) { };
})(MyObject);
归根结底,如果你不需要的话,就没有必要采用这种方法,但也没有必要改变它,因为它工作得很好,而且实际上有一些优点。
发布于 2014-11-07 04:14:34
此模式提供了一个作用域,您可以在其中定义在全局作用域中不可见的助手函数:
(function (root) {
function doFoo() { ... };
root.myFunction = function (foo) {
//do something
doFoo();
//do something else
};
})(MyObject);
doFoo
是匿名函数的本地函数,不能从外部引用它。
https://stackoverflow.com/questions/26788397
复制相似问题