4

I had this code :

function (i)
{
    alert(i);
}(3);

And it wasn't working , So After StackOverFlow Question - I changed it to :

 (function(i){ alert(i); })(3); 

And it works.

I had to () wrap all the code.

But then I saw this code on other site :

function addLinks () {
    for (var i=0, link; i<5; i++) {
        link = document.createElement("a");
        link.innerHTML = "Link " + i;
        link.onclick = function (num) {
            return function () {
                alert(num);
            };
        }(i); // <=== What about this ? there is no () wrapper... so how does it work ?
        document.body.appendChild(link);
    }
}
window.onload = addLinks;

I wanted to ask what is the role for the (i) part ? Is it executing something ?

And if it Does why Its not in a pattern of :

(function(i){ alert(i); })(3);

I mean where is the wrappers of () ?

Adam Zalcman
  • 26,643
  • 4
  • 71
  • 92
Royi Namir
  • 144,742
  • 138
  • 468
  • 792
  • 2
    possible duplicate of [Explain JavaScript's encapsulated anonymous function syntax](http://stackoverflow.com/questions/1634268/explain-javascripts-encapsulated-anonymous-function-syntax) – Quentin Nov 02 '11 at 11:03
  • 1
    Not a duplicate; the other doesn't ask (and the answers don't explain) anything about why `link.onclick = function (num) { ... }(i);` works *without* the function being wrapped in parentheses, which it seems to me is the main question. – cHao Nov 02 '11 at 11:10
  • I think I got the Problem : there is a difference between `var t= function(){alert('1')}();` to just write : `function(){alert('1')}();` Can YOU PLEASE EXPLAIN WHY ? http://jsbin.com/utumin/2/edit#source – Royi Namir Nov 02 '11 at 11:12
  • It is actually the same as the problem described in the question I suggested was a duplicate, and the accepted answer there does cover this case — it is just that being on the right hand side of an assignment is another place that only an expression can be. – Quentin Nov 02 '11 at 11:19
  • 1
    The question and accepted answer appear unrelated (no matter how related they actually are). There's a comment that kinda sorta hints at the answer to this question, but that's it. Anyone asking this question and seeing that answer would leave disappointed. – cHao Nov 02 '11 at 11:29
  • @cHao I Agree - I didnt get an ANSWER (p.s. there is still no accepted answer) – Royi Namir Nov 02 '11 at 11:31

2 Answers2

4

The compiler needs to differentiate between function declaration statement and function definition expression. You can only call functions in expressions.

When the keyword function appears after '=' or '(' the compiler knows this must be a function definition expression (since only expressions and not statements are allowed after '=' or '(') and allows you to call it immediately. When the keyword function starts a new statement the compiler assumes it to be a function declaration statement and hence you can't call the function immediately.

Note that function declaration statement requires you to name the function. This allows you to call it later. You may omit the function name in function definition expressions (and you can call them immediately).

Edited

all the bold fonts were made by Royi Namir the OP: those bold words are the key for understanding.

this is the most logical Explanation after a lot of tests.

See This

http://jsbin.com/imetan/edit#javascript,html

Royi Namir
  • 144,742
  • 138
  • 468
  • 792
Adam Zalcman
  • 26,643
  • 4
  • 71
  • 92
  • JavaScript compiler? JavaScript is being interpreted, rather than being compiled. – Rob W Nov 02 '11 at 11:29
  • Most modern JS implementations compile the script before running it. The line's a lot blurrier between compiled and interpreted languages these days. – cHao Nov 02 '11 at 11:32
  • 1
    +1 for being the least confusing and most logical explanation :) – cHao Nov 02 '11 at 13:05
0

The (i) part is passing the value of i as parameter to the anonymous function (function without name) which is declared as the onclick event handler, that's all. It doesn't really "do" anything.

Sorry, I stand corrected.. the (i) is executing the function passing i as parameter. This results in the onclick actually being such function:

function (num) {
    alert(num);
};

If you will try to access the variable i just like this from the function you'll always end up with its final value, 5 in this case.

Shadow The GPT Wizard
  • 66,030
  • 26
  • 140
  • 208
  • the values here will be 1,2,3,4,5 since there is closure...I tested it already. – Royi Namir Nov 02 '11 at 11:04
  • Wait. It definatly does something. – J. Holmes Nov 02 '11 at 11:06
  • I think I got the Problem : there is a difference between `var t= function(){alert('1')}();` to just write : `function(){alert('1')}();` Can YOU PLEASE EXPLAIN WHY ? – Royi Namir Nov 02 '11 at 11:11
  • With the first expression, you're storing the function return value in variable, executing it while doing it. In the second expression you gave you just self invoke the function without storing its return value. – Shadow The GPT Wizard Nov 02 '11 at 11:15
  • 1
    JS normally doesn't care about return values, though. (It'll happily discard a return value if you don't put it in a variable.) So why is it caring here? – cHao Nov 02 '11 at 11:17
  • @ShadowWizard I dont need to store the return value - just to see the alert.... so why there is no alert ? – Royi Namir Nov 02 '11 at 11:17
  • 1
    You mean in this code `function(){alert('1')}()`? Because it's syntax error. When function has no name it must be either assigned to variable first, or self invoking itself using `(` and `)` wrappers to tell the JIT compiler "I'm independent block" – Shadow The GPT Wizard Nov 02 '11 at 12:29