Strange behavior of JS functions in if statement WHY?

Why the following code will return "obvious", "surprise!" (and, finally, "how did it happen?"). It should return "expected", right? In the first if

we used anonymous functions, in the second we used the "named" functions.

var a = 5;
if (a == 5) {
    var b = function () {
        return "obvious";
    };
} else {
    var b = function () {
        return "never";
    };
}

if (a == 5) {
    function c() {
        return "expected";
    }
} else {
    function c() {
        return "surprise!";
    }
    function d() {
        return "how come?";
    }
}

alert(b());
alert(c());
alert(d());

      

So this means function a(){} is NOT equal to var a = function (){}

.

So the second question is, why does JS need this peculiar behavior? What is the use of this?

+3


source to share


3 answers


All variable declarations and function declarations are hoisted to the top of the scope, in this case the top of the script. This means that the code is interpreted as if it were,

var a,b;
function c() { 
    return "expected"; 
} 
function c() { 
    return "surprise!"; 
} 
function d() { 
    return "how come?"; 
} 

a = 5; 
if (a == 5) { 
    b = function () { 
        return "obvious"; 
    }; 
} else { 
    b = function () { 
        return "never"; 
    }; 
} 

if (a == 5) { 
} 
else { 
} 

alert(b()); 
alert(c()); 
alert(d()); 

      

Note that the last if statement is empty, since all the function declarations they contained were hoisted. The second function declaration c

obscures the first.

I recommend that you avoid using the funciton declaration syntax in a block statement. This is technically not legal JavaScript, but every browser supports it, even if it is confusing, as you noted.



Function a () {} is NOT equal to var a = function () {}.

Right. It never happened.

So the second question is, why does JS need this peculiar behavior? What is the use of this?

JavaScript hoists function declarations so that a function declared later in the script is used by a function earlier in the script. This allows for much more flexibility in organizing your code.

+4


source


No, it doesn't have to be, because the semantics of the function definition operators are not what you seem to think they are.

Function definition statements always go up to the top of the enclosing function (or scope). When there is more than one function definition statement with the same name, the last one wins. This is not a dynamic runtime. The statement of function definition statements within blocks of conditional code should indeed be prohibited syntactically, but it is not. Just don't do it.



You can, of course, use function constructor expressions to create function objects that you assign to variables. This will work as you expect.

+7


source


@Pointy is correct. The c () and d () functions are declared before the first if statement is evaluated. So when you trigger alerts, they do what they do.

+1


source







All Articles