7

以下是定义 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);
        }
    };
};
4

3 回答 3

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(立即调用函数表达式)允许模拟静态变量(通过单个实例保持其值的变量)。例如:

var module = (function() {
    var x = 0;

    return {   get: function()  { return x },
               set: function(n) { x = n }
    };

})();

以上是模块模式的教科书示例。由于该函数被立即调用,因此变量x被实例化并且返回值(对象)被赋予给module. x除了使用为我们提供的getset方法外,我们别无他法。因此,x是静态的,这意味着每次使用时都不会覆盖其变量module

module.set(5);

module.get(); // 5

另一方面,让我们看一个module声明为函数的示例:

// assume module was made as a function

module().set(5);

module().get(); // 0

当我们调用变量时module()x每次都会被覆盖。所以我们在每次调用时有效地使用moduleand的不同实例。xmodule

于 2012-12-04T20:00:36.673 回答
3

差别比较大。

在第一种情况下,在BW.Timer第一次遇到时执行,即分配给的静态版本BW.Timer。在这种情况下,BW.Timer.Add(1)可以使用。每个调用都BW.Timer将是同一个对象。

在第二种情况下,BW.Timer第一次遇到时不执行,而是必须调用的函数引用BW.Timer()。要Add使用,必须是这种情况BW.Timer().Add(1)。此外,您可以发出var timer = new BM.Timer();. 的每个实例在BW.Timer()这里都是唯一的。

于 2012-12-04T20:02:06.013 回答
2

在第一个示例BW.Timer中引用了一个自执行函数返回的对象,而在第二个示例中它引用了一个函数对象,换句话说,它是一个可以执行的函数BW.Timer()

于 2012-12-04T20:01:48.083 回答