-1

If I have-

function outer(){
    function inner(){}
}

inner is not visible outside outer

but if I have something like this-

if (true) {                  // the scope for foo starts here
  function foo() {
    return 'first';
  }
// the scope for foo ends  on the } in next line
}
else {
  function foo() {
    return 'second';
  }
}

then,

typeof foo == function   // true, foo is visible here, Why?
Farhan stands with Palestine
  • 13,890
  • 13
  • 58
  • 105
  • 3
    No the scope of `foo` does not start the the if block. Except of `let` js does not have block scopes but function based scopes. Beside that is is not a valid syntax to define a function with in an if block. – t.niese Jun 05 '16 at 14:27
  • A function itself is a "scope", everything inside it is not bleeding out of it but it can access global variables outside the function. foo.Prototype.bar = function () {} can extend the foo function. The example you use ALWAYS declares the function, it is always true or false. – poashoas Jun 05 '16 at 14:27
  • 1
    JavaScript isn't block-scoped, instead it is function-scoped. "*the scope for foo ends on the } in next line*" is entirely false. – Derek 朕會功夫 Jun 05 '16 at 14:31

1 Answers1

1

Because if/else statements have the scope of whatever they're inside of (whether global or inside of another function). Once you've exited the if/else logic, you will have defined foo one way or the other.

In this case, if true is true (which it is) then foo would be set to that first function. If it weren't true, foo would still be set to the second function.

You're correct that variables inside of functions go out of scope, but the same is not true for if/else statements.

For example:

a = 5;
var add_ten = function(a){
    b = a + 10;
    return b;
}
c = add_ten(a)
console.log(b) // B will not be set

if(a > 1){
    b = a + 10;
}
console.log(b) // B will be set

This is a good thing: You want to be able to use those variables later.

EDIT: I should mention that, as the comment below detailed, conditionally declaring functions is a bad practice, and should be avoided. Instead, you should declare two functions with two different names outside of your if/else statement, and conditionally call one of them. When one is triggered, the other will not execute even though it has been defined, so there's no risk of both running (mentioned in case you were worried about that).

Robert Townley
  • 3,414
  • 3
  • 28
  • 54
  • Defining a function within an `if` block is not valid. ( [Function declarations inside if/else statements?](http://stackoverflow.com/questions/10069204) ). What do you mean with `[...]You're correct that variables inside of functions go out of scope, but the same is not true for if/else statements.[...]`? This is very ambiguous and misleading. – t.niese Jun 05 '16 at 14:35