5

I am reading about Function Declarations vs. Function Expressions, and I cannot figure out the meaning of following statement:

Function Declarations occur as standalone constructs and cannot be nested within non-function blocks.

Someone please to explain with an exemple what does the author means, precisely by: "...cannot be nested within non-function blocks".

Link is: https://javascriptweblog.wordpress.com/2010/07/06/function-declarations-vs-function-expressions/

Adib Aroui
  • 4,981
  • 5
  • 42
  • 94
  • 1
    Further reading: [*What are the precise semantics of block-level functions in ES6?*](http://stackoverflow.com/questions/31419897/what-are-the-precise-semantics-of-block-level-functions-in-es6). – RobG Aug 11 '15 at 01:02

4 Answers4

2

I dont know the author meant it was physically impossible or more of it shouldn't be done. From my understanding what the author was saying is that this:

var y = true;
if (y) {
    function example() {
    alert('hi');
    return true;
   }
}

Here the function is declared inside a conditional statement, which is fine since x is true, but if it were false that function would never be declared and when we do want to the call the example function nothing will happen because it was never declared. So it should be

function example() {
"use strict";
return true;
}
var y = true;
if (y) {
    example();
}

In the above code we still call the example function if the condition is met, however since example is defined outside the condition statement we can use it regardless of the conditional statement. This Post has more information about it. Hopefully this is what you meant

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
code
  • 1,127
  • 7
  • 14
  • yeaaah very persuading and true. Thanks for your quick idea. waiting for timer to expire +1 – Adib Aroui Aug 10 '15 at 23:56
  • I also recommend reading @Pointy answer, it gives more insight about the idea behind – Adib Aroui Aug 11 '15 at 00:04
  • 1
    @code, could you please update this dead link "This Post has more information about it" or replace it with the info you know. It would be helpful to understand the points you were referring, Thanks. – Ashok M A Feb 27 '17 at 10:23
  • i still don't get the idea, would you please make a small effort to explain it a little bit more. – Waleed Mohsin Aug 05 '17 at 07:15
2

Taken at face value, the statement:

Function Declarations occur as standalone constructs and cannot be nested within non-function blocks.

is wrong. It's possible to put function declarations inside blocks, as examples in the article show. The reason that it's warned against is that the behaviour differs in different browsers. In most browsers (not certain versions of IE and Firefox), such functions are declared regardless of whether execution enters the block or not, e.g.:

if (false) {
  function foo(){}
}

foo is declared and available within the outer scope. This is exactly the same with variable declarations:

if (false) {
  var x = 3;
}

In the above, x is declared regardless of whether the block is executed or not. The assignment of the value, however, only occurs if the block is entered.

Back to functions. The reason function declarations in blocks is warned against is that firstly, it infers that the function is only created if the block is entered, which is incorrect for most browsers but not all. Secondly, and more importantly, it's because different browsers have different behaviour.

Some interesting reading:

Also note that function statements are warned against in ES5 strict mode and may be introduced in some future version of ECMAScript.

Finally, this behaviour is addressed directly in ECMA-262 ed 6 in Appendix B 3.3.3 and Appendix B 3.4.

Community
  • 1
  • 1
RobG
  • 142,382
  • 31
  • 172
  • 209
  • The good part is that no one can agree on a terminology: function statement, function declaration as a statement, function declaration within blocks, etc. and browsers can't agree on what to do about it. They even flip–flop in how they handle it between versions. Fun! ;-) – RobG Aug 11 '15 at 02:00
  • Thanks RobG for this big science and sharing. I will be reading your answer when have time and enough knowledge to understand it. I somehow agree with you since also the link I gave in OP contains ideas about browsers versions exceptions. Again thanks. – Adib Aroui Aug 11 '15 at 12:38
  • bro you should test the code in some browser to provide the reference, I tested it in chrome 59.0, guess what if the condition is false, it gives me an exception – Waleed Mohsin Aug 05 '17 at 07:17
  • @Vick_Pk—perhaps you missed "**the behaviour differs in different browsers**" and "**…is incorrect for *most* browsers but not all**". – RobG Aug 05 '17 at 11:54
1

I think it means you cannot define functions arbitrarily in the code, see below.

if true {
  function funName(){};
}

funName will not be a function in this case, it will cause an error.

Alexei Darmin
  • 2,079
  • 1
  • 18
  • 30
1

Consider the humble if statement:

function whatever() {
  // ...
  if (something === somethingElse) {
    function aFunction() {
      // ...
    }

    // more code ...
  }

  aFunction(5, 6, 7);

Now, that code is weird. The function is declared inside the if block. But function declarations are hoisted! So what does that mean?

More weird: what if there's a different declaration for "aFunction" in the else clause?

A fundamental aspect of the weirdness from code like that is that function declarations are treated as if they occur at the top of the scope (that is, they're "hoisted"). For that reason, a function declaration inside some other sort of block is just inherently ambiguous and strange.

Note that function instantiation via function expressions are not weird, because those happen as part of running code, like object initialization expressions.

Pointy
  • 405,095
  • 59
  • 585
  • 614
  • Thanks Pointy, this is it. convincing and well explained +1 – Adib Aroui Aug 10 '15 at 23:57
  • "*But function declarations are hoisted*" but some browsers treat that pattern as a function statement, so not "hoisted" and the function is only created if the block is entered (e.g. IE 11). – RobG Aug 11 '15 at 00:40