1

I had this code:

Javascript

(function() {
    function read() {...}    
})();

HTML

<body onload="read()">

Console said, read is undefined. After deleting the IIFE it worked, why?

Thanks. :)

loveNoHate
  • 1,549
  • 13
  • 21
  • 3
    Google "javascript scope" before you try to use patterns like IIFE. – Denys Séguret Jan 06 '14 at 12:50
  • 1
    Why downvote a perfectly good question? – Dan Abramov Jan 06 '14 at 12:51
  • 1
    That's the very purpose of an IIFE, encapsulation. – elclanrs Jan 06 '14 at 12:51
  • @DanAbramov How would you search about IIFE and not see it's about scope and encapsulation ? – Denys Séguret Jan 06 '14 at 12:52
  • @dystroy: It took me several months to fully grok JavaScript scope / closures. The problem usually is that you *think* you understand them (as a beginner JS programmer coming from languages like C#) but in fact you don't, and you find it out slowly, mistake by mistake, until you fully realize your incompetence and go about fixing it. – Dan Abramov Jan 06 '14 at 12:54
  • @dystroy How could I sanely know to google "javascript scope" if I seemingly don't know about it? [/Protest note] How would you explain that to a six year old (see comment at JaredPar's answer)? – loveNoHate Feb 25 '14 at 10:59
  • @dollarVar Well, you knew the IIFE word. So you could have tried to learn what an IIFE was... – Denys Séguret Feb 25 '14 at 11:02
  • @dystroy Ok, I used that inline code only there once and never will again. ;) Are you reading the explanation to my only question (why?) down @JaredPar's? – loveNoHate Feb 25 '14 at 11:07
  • possible duplicate of [What is this (IIFE) construct in javascript?](http://stackoverflow.com/questions/8228281/what-is-this-iife-construct-in-javascript) – loveNoHate Oct 01 '14 at 18:30

4 Answers4

3

Here's a long but satisfying explanation about JavaScript scope and closures.

Since you declare read inside a function, it is local to that function.
Anything you declare inside a function will be local to it.

You can explicitly put it into global scope by assigning it as a property to window:

(function() {
    function read() {...}    

    window.read = read;
})();
Dan Abramov
  • 264,556
  • 84
  • 409
  • 511
2

Writing

(function() {
    function read() { ... }
})();

Is very nearly the same thing as writing

(function() {
    var read = function() { ... } //this is different, but not significantly so
                                  //for purposes of teaching this point
})();

and I think you should already understand why a var declared inside a function is not available outside of that function's scope.

The behavior of a function definition (function read() { ... }) is slightly different from the behavior of assigning a function expression to a variable (var read = function() { ... };) in terms of when the name of the function and the function become associated, but the two are otherwise identical.

ellisbben
  • 6,352
  • 26
  • 43
1

Because it isn't defined globally. It's only been defined within the scope of that immediately invoked function. To make it global either use this:

function read() {...}    

(function() {
    ...
})();

Or this:

(function() {
    window.read = function() {...}    
})();

Or better yet, just bind the onload event within the immediately invoked function:

(function() {
    function read() {...}
    window.onload = read;
})();
p.s.w.g
  • 146,324
  • 30
  • 291
  • 331
1

In this case the definition of read is inside the IIFE. This limits the scope of the function to the IIFE and any child functions inside of it. The handler for onload is executed in the global scope and hence doesn't have access to read

JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
  • Hey, I just came here to delete that question, but stumbled upon "voted for close because off-topic"...eah, ok? However I still need to manage creating an inner image of how javascript from an external `.js` is parsed...can I imagine it is written in the `HTML` like if it would be in `` (without `src`, plainly)? Thanks, wahy, I chose you because you have the most rep. (Y) – loveNoHate Feb 25 '14 at 00:18