1
var Mod=(function () { say('hello'); 
             var say =  function (m){ console.log(m); }; 
              return ({a: 'b'}); }
 )();

VM3488:1 Uncaught TypeError: say is not a function(…)(anonymous function) @ VM3488:1(anonymous function) @ VM3488:1

but this works

var Mod = (function () { 
              say('hello');  
              function say (m){ console.log(m); };
              return ({a: 'b'}); }
     )();

why is this happening ? If I need to use "say" as a public function in my Mod, how is that going to work ?

Ka Pr
  • 75
  • 1
  • 5
  • It has nothing to do with the IIFE but read this: http://stackoverflow.com/questions/3887408/javascript-function-declaration-and-evaluation-order/3887590#3887590 – slebetman Aug 13 '16 at 04:48

2 Answers2

2

That's because function expressions are not hoisted. The first one is a a function expression and the second one is a function statement which is hoisted.

Also note that neither of your code snippets exports the say function so it remains as a private function.

Ram
  • 143,282
  • 16
  • 168
  • 197
  • thx for the quick reply. What pattern do I need to follow if I need to expose "say" as a public method ? – Ka Pr Aug 13 '16 at 04:58
  • @KaPr It can be a method of the returned object: `return { say: say, a: 'b' }`. Or in ES2015: `return { say /* shorthand syntax */, a: 'b' }` – Ram Aug 13 '16 at 04:59
1

Function expressions are not hoisted, which is why you are getting an error. You can move the expression before invocation and return the variable as a response to your IFFE. Now you can call say() in other places.

var Mod=(function () { 
             var say =  function (m){ console.log(m); }; 
              say('hello'); 
              return {say: say}; 
})();

Mod.say("say what you want to say.");
Yasin Yaqoobi
  • 1,888
  • 3
  • 27
  • 38