这种定义JS对象的方式有什么用处吗?
我维护一些遗留代码,我注意到使用了以下用于定义对象的模式:
var MyObject = {};
(function (root) {
root.myFunction = function (foo) {
//do something
};
})(MyObject);
这有什么目的吗? 这相当于只是做了以下事情吗?
var MyObject = {
myFunction : function (foo) {
//do something
};
};
我不打算进行一个神圣的探索来重构整个代码库以符合我的喜好,但我真的很想了解这种迂回定义对象的原因。
谢谢!
它被称为模块模式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
目的是限制闭包内的函数的可访问性 ,以防止其他脚本在其上执行代码。 通过它包裹封闭你正在重新定义执行范围为封内部的所有代码,并有效地创建一个私人范围。 有关更多信息,请参阅此文章:
http://lupomontero.com/using-javascript-closures-to-create-private-scopes/
从文章:
JavaScript中最着名的问题之一是它依赖于全局范围,这基本上意味着你在一个函数之外声明的任何变量都存在于同一个名称空间中:不祥的窗口对象。 由于网页的性质,来自不同来源的许多脚本可以(并且将)在共享全局范围的相同页面上运行,并且这可能是非常糟糕的事情,因为它可能导致名称冲突(具有相同名称的变量被覆盖)和安全问题。 为了最大限度地减少这个问题,我们可以使用JavaScript强大的闭包来创建私有范围,我们可以确定我们的变量对页面上的其他脚本是不可见的。
码:
var MyObject = {};
(function (root) {
function myPrivateFunction() {
return "I can only be called from within the closure";
}
root.myFunction = function (foo) {
//do something
};
myPrivateFunction(); // returns "I can only be called from within the closure"
})(MyObject);
myPrivateFunction(); // throws error - undefined is not a function
Adavtages:
1。第一个模式可以作为一个模块,它接受一个对象并且修改一些对象并返回该对象。 换句话说,你可以定义这样的模块如下
var module = function (root) {
root.myFunction = function (foo) {
//do something
};
}
并使用它:
var obj = {};
module(obj);
所以这个模块可以重复使用,以备后用。
2 。 在第一种模式中,已经提到了其他答案,您可以定义一个私有范围来存储私有资源,例如私有资源和方法。 例如,考虑这段代码
(function (root) {
// this plays as a private property
var factor = 3;
root.multiply = function (foo) {
return foo * factor;
};
})(MyObject);
3 。 另一个优点是可以使用这种模式为所有类型的对象(如数组,字面对象,函数)添加方法或属性
function sum(a, b){
return a + b;
}
(function (root) {
// this plays as a private property
var factor = 3;
root.multiply = function (foo) {
return foo * factor;
};
})(sum);
console.log(sum(1, 2)); // 3
console.log(sum.multiply(4)); // 12
注:在我看来,主要优势可能是第二个(创建私人范围)
链接地址: http://www.djcxy.com/p/17061.html