-3

var x = 3;
function func(randomize) {
    if (randomize) {
        var x = Math.random();
        return x;
    }
    return x;
}
console.log(func(false));

As you can see from above code, if statement never be true but the x value is undefined, i would like to understand how variable declaration works in javascript. Any references also be helpful.
Update:
Can anybody explain why variable was re-declared to undefined and how it is related to hoisting in javascript

Sinan Ünür
  • 116,958
  • 15
  • 196
  • 339
nivas
  • 3,138
  • 3
  • 16
  • 15
  • Classic hoisting – nicovank Apr 26 '17 at 12:58
  • 2
    I think the -3 is excessive. It has a MCVE, and while it may be obvious to those fluent in JS, it's not a terrible question. – Carcigenicate Apr 26 '17 at 13:00
  • I know little about hosting in javascript, but the variable `x` is defined outside the function and we are not returning `function reference` – nivas Apr 26 '17 at 13:01
  • 1
    Returning function references doesn't have anything to do with hoisting. If you define `x` inside the function with `var`, it becomes a local variable everywhere inside the function, even if the definition was inside an if block that was never executed. – JJJ Apr 26 '17 at 13:03
  • 1
    the part i get confused how variable was `redeclared` as `if statement was not true` – nivas Apr 26 '17 at 13:05
  • 1
    @T.J.Crowder Actually, this question is subtly different than the one to which you linked. – Sinan Ünür Apr 26 '17 at 13:07
  • @SinanÜnür: Not in any meaningful way. But by all means, find the duplicate adding the `if` in there -- I guarantee you there is one. Probably several. – T.J. Crowder Apr 26 '17 at 13:18
  • 1
    @Carcigenicate: **Completely** agree. I wouldn't vote the question up, but I certainly wouldn't downvote it. Just close, perhaps comment to point to the specific way in which the linked question is relevant. – T.J. Crowder Apr 26 '17 at 13:25
  • @T.J.Crowder i was actually reading a [book](http://exploringjs.com/es6/ch_core-features.html#sec_from-var-to-const) and i googled before i post the question but could not find any solutions so i posted question here – nivas Apr 26 '17 at 13:26
  • 2
    @T.J.Crowder This site is extra brutal lately. Wrote up what I thought was a great question yesterday, and it got downvoted within half a minute of posting (it's at +5 now, so it obviously wasn't a bad question). And like 10 minutes ago I saw a 20 second old question with a downvote, when it really wasn't a terrible question. I think people need to be as selective with their downvotes as they are with their upvotes. – Carcigenicate Apr 26 '17 at 13:30
  • @Carcigenicate: That **would** be a great improvement. – T.J. Crowder Apr 26 '17 at 13:32

2 Answers2

2

Because func is in essence:

function func(randomize) {
    var x;
    if (randomize) {
        x = Math.random();
        return x;
    }
    return x;
}

Variables in JavaScript have function scope, not block scope with which you might be familiar from other languages. This results in the hoisting behavior you observe:

What does happen is that variable and function declarations are put into memory during the compile phase, but stays exactly where you typed it in your coding.

...

JavaScript only hoists declarations, not initializations. (emphases mine)

That is, even though inside func you declare x in the if block, during compile time its declaration is moved to function level where it shadows x in global scope. However, it is only initialized if the argument to func is true which leads to the behavior you observe.

See also let:

"use strict";
var x = 3;
function func(randomize) {
    if (randomize) {
        let x = Math.random();
        return x;
    }
    return x;
}
console.log(func(false));
console.log(func(true));
Community
  • 1
  • 1
Sinan Ünür
  • 116,958
  • 15
  • 196
  • 339
  • We don't need **yet another** answer to this question. – T.J. Crowder Apr 26 '17 at 12:58
  • @Sinan unur He is talking about [this](http://stackoverflow.com/questions/37508842/javascript-variable-hoisting-confusion) – Jins Peter Apr 26 '17 at 13:01
  • @JinsPeter Well, if [that](http://stackoverflow.com/questions/37508842/javascript-variable-hoisting-confusion) is to be the *canonical answer* to all hoisting questions, then you or T.J. might want to put some effort into improving its presentation. – Sinan Ünür Apr 26 '17 at 13:03
  • 1
    @SinanÜnür: There are dozens -- hundreds -- of dupetargets for this, I wouldn't be surprised if there were better ones. By all means go and look, and flag up any others you think are relevant, we can include them. And of course, if you think that question's answers are lacking post an answer there. – T.J. Crowder Apr 26 '17 at 13:20
  • 1
    @Kinduser: I would suggest finding the earlier example of this pattern (again, it's there) and posting the answer there if it doesn't just duplicate what's already been said there. Posting an answer on a question closed half an hour earlier is clearly not cool. – T.J. Crowder Apr 26 '17 at 13:31
  • 1
    Thanks @SinanÜnür for taking your time and addressing important point `JavaScript only hoists declarations, not initializations`. that's what confused me, that's not told most of the times when they answer any question about hoisting – nivas Apr 26 '17 at 13:52
-2

You define a new variable var x in your function and thus overwrite the outer variable x.

Imanuel
  • 3,596
  • 4
  • 24
  • 46