简体   繁体   中英

What is the difference in the following JS syntax?

Following are two ways to define BW.Timer. Can someone tell me what the difference is? I am not certain the first is even valid, but if it is valid, what is different about using the myfunc=(function(){}()) syntax?

BW.Timer = (function () {
    return {
        Add: function (o) {
            alert(o);
        },
        Remove: function (o) {
            alert(o);
        }
    };
} ());

And...

BW.Timer = function () {
    return {
        Add: function (o) {
            alert(o);
        },
        Remove: function (o) {
            alert(o);
        }
    };
};

The first is the return-value of the immediately-invoked function. The second is a function. It essentially comes down to what the difference is between these:

var f = (function() { return 0; })();

var f = function() { return 0; };

Since the first function is called immediately, the value of 0 is given to the variable f . The first f is not a function. However, the second f we must call in order to get the value:

f(); // 0

It follows that in your example, the first BW.Timer is the object literal itself and the second is a function returning an object literal. You must call the function in order to get to the object:

BW.Timer().Add(x);

Why use the first then?

You might ask yourself why one would use a syntax like a = (function() { return {}; })() instead of a = {} , but there's a good reason. An IIFE (Immeditately-Invoked Function Expression), unlike a regular function allows the emulation of static variables (variables that maintain their value through a single instance). For example:

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

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

})();

The above a text-book example of the Module Pattern . Since the function is called right away, the variable x is instantiated and the return value (the object) is given to module . There's no way we can get to x other than by using the get and set methods provided for us. Therefore, x is static, meaning its variable won't be overridden each time you use module .

module.set(5);

module.get(); // 5

On the other hand, let's see an example where module is declared as a function instead:

// assume module was made as a function

module().set(5);

module().get(); // 0

When we call module() the x variable is overridden each time. So we're effectively using different instances of module and x each time we call module .

The difference is rather large.

In the first case, BW.Timer is executed when it is first encountered, and that is the static version assigned to BW.Timer . In that instance, BW.Timer.Add(1) may be used. Each call to BW.Timer will be the same object.

In the second case, BW.Timer is not executed when first encountered, and instead is a function referece which must be invoked BW.Timer() . For Add to be used, this must be the case BW.Timer().Add(1) . Also, you can issue var timer = new BM.Timer(); . Each instance of BW.Timer() will be unique here.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM