Extra parentheses on function [duplicate]

泄露秘密 提交于 2019-12-04 18:17:58

问题


Possible Duplicate:
What do parentheses surrounding a JavaScript object/function/class declaration mean?
What does this “(function(){});”, a function inside brackets, mean in javascript?
A Javascript function

I encountered markup similar to this:

var something = (function(){
    //do stuff
    return stuff;
})()
document.ondblclick = function(e) { alert(something(e)) };

I don't understand the opening ( and closing )() in the something variable. Could you explain the difference to writing it like this?

var something = function(){
    //do stuff
    return stuff;
};

Thanks!


回答1:


It's probably easier to understand if you leave the redundant parens out because they serve no purpose:

var something = function() {
    return 3;
} // <-- a function. 
(); // now invoke it and the result is 3 (because the return value is 3) assigned to variable called something 

console.log(something) //3 because the function returned 3 

var something = function() {
    return 3;
}; // a function is assigned to a variable called something

console.log(something) //logs the function body because it was assigned to a function
console.log(something()) //invoke the function assigned to something, resulting in 3 being logged to the console because that's what the function returns



回答2:


(function(){ ... }) is a (anonymous) function expression, you could e.g. assign that value to a variable.

The brackets behind it will immidiately execute the function expression, resulting in the return value of the function (in here: stuff). The construct is called IIFE.

When stuff is a function (which I assume, because you invoke something lateron), this is called a closure - the returned function (stuff, assigned to something) still has access to the variables in the execution context of that anonymous function.




回答3:


On the question what it does, read all the comments and other answers. They are absolutely right.

Why would you want to use it? You find this pattern very often when using closures. The intent of the following code snippet is to add an event handler to 10 different DOM elements and each one should alert it’s ID attribute (e.g. “You’ve clicked 3″). You should know that if this was your actual intent, then there is a much easier way to do this, but for academic reasons let’s stick with this implementation.

var unorderedList = $( "ul" );
for (var i = 0; i < 10; i++) {
    $("<li />", {
        id: i,
        text: "Link " + i,
        click: function() {
            console.log("You've clicked " + i);
        }
    }).appendTo( unorderedList );
}

The output of the above code may not be what you first expect. The result of every click handler will be “You’ve clicked 9″ because the value of i at the point the event handler was fired is “9″. What the developer really wanted is for the value of i to be displayed at the point in time the event handler was defined.

In order to fix the above bug we can introduce a closure.

var unorderedList = $( "ul" ), i;

for (i = 0; i < 10; i++) {
    $("<li />", {
        id: i,
        text: "Link " + i,
        click: function(index) {
            return function() {
                console.log("You've clicked " + index);
            }
        }(i)
    }).appendTo( unorderedList );
}

You can execute and modify the above code from jsFiddle.

One way to fix the above code is to utilize a self-executing anonymous function. That is a fancy term that means we are going to create a nameless function and then immediately call it. The value of this technique is that the scope of the variable stays within the function. So, first we will surround the event handler content in a function and then immediately call the function and pass in the value of i. By doing that, when the event handler is triggered it will contain the value of i that existed when the event handler was defined.

Further reading on closures: Use Cases for JavaScript Closures




回答4:


Check the JavaScript FAQ section, too: Here are some pretty good explanations and examples

Ok, why should you use this:

Suppose my script is running, and there are a couple of things (I'm, for instance, looping through a nodes list) I might be needing later on. That's why I might choose to do something like this:

for(var i=0;i<nodesList.lenght;i++)
{
    if (nodesList[i].id==="theOneINeed")
    {
        aClosure = (function(node,indexInNodesList)//assign here
        {
            return function()
            {
                node.style.display = 'none';//usable after the parent function returns
                alert(indexInNodesList+ ' is now invisible');
            }
        })(nodesList[i],i);//pass the element and its index as arguments here
        break;
    }
}
i = 99999;
aClosure();//no arguments, but it'll still work, and say i was 15, even though I've just 
//assigned another value to i, it'll alert '15 is now invisible'

What this enables me to do is to prevent function arguments from being garbage collected. Normally, after a function returns, all its var's and arguments are GC'd. But in this case, the function returned another function that has a link to those arguments (it needs them), so they're not GC'ed for as long as aClosure exists.

As I said in my comment. Google closures, practice a bit, and it'll dawn on you... they really are quite powerful




回答5:


All of the answers were good, but I think the simplest answer has been skimmed over:

var something = (function(){
    //do stuff
    return stuff;
})()

After this code executes, something becomes stuff. The function that returned stuff is executed before something is assigned.

var something = function(){
    //do stuff
    return stuff;
};

After this code executes, something is a function which returns stuff. The function that returns stuff was never executed.



来源:https://stackoverflow.com/questions/11795912/extra-parentheses-on-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!