以下是两种定义BW.Timer的方法。有人能告诉我有什么区别吗?我不确定第一个是否有效,但如果它有效,那么使用myfunc=(function(){}())
语法会有什么不同?
BW.Timer = (function () {
return {
Add: function (o) {
alert(o);
},
Remove: function (o) {
alert(o);
}
};
} ());
和...
BW.Timer = function () {
return {
Add: function (o) {
alert(o);
},
Remove: function (o) {
alert(o);
}
};
};
答案 0 :(得分:9)
第一个是立即调用函数的返回值。第二个是功能。它基本上归结为它们之间的区别:
var f = (function() { return 0; })();
var f = function() { return 0; };
由于立即调用第一个函数,因此将值0赋予变量f
。第一个f
不是函数。但是,我们必须调用第二个f
才能获得值:
f(); // 0
在你的例子中,第一个BW.Timer
是对象文字本身,第二个是返回对象文字的函数。您必须调用该函数才能访问该对象:
BW.Timer().Add(x);
您可能会问自己为什么会使用a = (function() { return {}; })()
而不是a = {}
这样的语法,但这是有充分理由的。与常规函数不同,IIFE(Immeditately-Invoked Function Expression)允许模拟静态变量(通过单个实例维护其值的变量)。例如:
var module = (function() {
var x = 0;
return { get: function() { return x },
set: function(n) { x = n }
};
})();
上面是Module Pattern的教科书示例。由于函数是立即调用的,因此变量x
被实例化,返回值(对象)被赋予module
。除了使用为我们提供的x
和get
方法之外,我们无法前往set
。因此,x
是静态的,这意味着每次使用module
时都不会覆盖其变量。
module.set(5);
module.get(); // 5
另一方面,让我们看一个将module
声明为函数的示例:
// assume module was made as a function
module().set(5);
module().get(); // 0
当我们调用module()
时,每次都会覆盖x
变量。因此,每次调用module
时,我们都会有效地使用x
和module
的不同实例。
答案 1 :(得分:3)
差异相当大。
在第一种情况下,BW.Timer
在第一次遇到时执行,这是分配给BW.Timer
的静态版本。在那种情况下,可以使用BW.Timer.Add(1)
。每次调用BW.Timer
都是同一个对象。
在第二种情况下,BW.Timer
在第一次遇到时不会被执行,而是一个必须被调用的函数referece BW.Timer()
。要使用Add
,必须是BW.Timer().Add(1)
。此外,您可以发出var timer = new BM.Timer();
。 BW.Timer()
的每个实例在这里都是唯一的。
答案 2 :(得分:2)
在第一个示例中,BW.Timer
引用了自执行函数返回的对象,而在第二个示例中,它引用了一个函数对象,换句话说,它是一个可以执行的函数BW.Timer()
。