2

From Eloquent Javascript by Marijn Haverbeke

Different JavaScript platforms in different browsers have traditionally done different things in that situation, and the latest standard actually forbids it.

but why is it bad?

function example () {
    function a () {} // Okay
    if ( something ) {
       function b () {} // Danger !
    }
}
lychee
  • 1,771
  • 3
  • 21
  • 31
  • Not all browsers handle that the same way... – Denys Séguret May 30 '15 at 19:29
  • Could you please share with us *how* browsers differ on this, and perhaps link to any particular statement from the ECMAScript standard that discourages this? – Sampson May 30 '15 at 19:30
  • I think its also largely pointless due to hoisting, the function would just be moved to the top of its parent function and exist regardless of the if statement. This is probably what he means when browsers handle it differently. http://www.adequatelygood.com/JavaScript-Scoping-and-Hoisting.html – Kevin F May 30 '15 at 19:31
  • Because different JavaScript platforms in different browsers have traditionally done different things in that situation. Your code will not be guaranteed to be working on all environments. – thefourtheye May 30 '15 at 19:34

3 Answers3

3

It's considered "bad" because its behavior is inconsistent and sometimes doesn't do what most people would expect. Consider the following snippet:

if (true) {
    function f() { return "t"; }
} else {
    function f() { return "f"; }
}

What would calling f() return? On IE and Firefox, it will return "t", but on Chrome and Safari, it will return "f". Why? A combination of hoisting and JavaScript's scoping rules. For information on how that works, see this question on JavaScript scoping and hoisting.

Effectively, this means that, on some browsers, the branch is completely ignored when it comes to function definitions using the function name() { ... } form. If you really need to do something like this (and you probably don't, since it would be very poor style, anyway), use the name = function () { ... } form instead, since that will not be hoisted, so the behavior is well-defined and will not be inconsistent across platforms.

Community
  • 1
  • 1
Alexis King
  • 43,109
  • 15
  • 131
  • 205
0

The short answer is already given to you, namely: such practice negatively affects the portability/compatibility of the solution between various browsers. What is even worse: it leads to the added ambiguity regarding the local variables, namely: which variables will be "visible" to which nested functions. Even though it could be considered allowed technique, but it doesn't mean that such technique is a good practice. "Code for the clarity" is the utterly important programming paradigm, so always try avoiding the practices which add to the ambiguity. Best regards,

Alexander Bell
  • 7,842
  • 3
  • 26
  • 42
0

This is standardized in ES6 and is valid to nest function declaration inside blocks. Here is the spec Block-Level-Function-Declarations

You can try in latest browsers with strict-mode turned on. And for reasons why that behavior is present in old environments look here: Functions

Blago Eres
  • 1,328
  • 12
  • 17