2

Please explain this to me, why am I getting 0 instead of 5?

Inside HTML file :

<script>
    var x = 5;
</script>
<div id="dv"></div>

Inside JS file :

$(function () {
  if(typeof x == 'undefined') {
    var x = 0;
    $("#dv").html(x);
  } else if (x == 5) {
    $("#dv").html(x);
  }
});

What am I missing here?

blowz
  • 23
  • 3
  • Where do you load the js file? Before or after the script tag where you assing `x`? – Ozan Apr 12 '17 at 13:04
  • 5
    It is hoisting `var x` inside the IIFE – gurvinder372 Apr 12 '17 at 13:04
  • @Ozan before, of course... the `x = 5` is loaded before – blowz Apr 12 '17 at 13:05
  • You are creating a local `x` in your code, which will overwrite the global one. Even though the `var x = 0` is mentioned after the `if` clause, `x` is still redeclared locally before the `if` (this is called hoisting). Then it will be undefined, in which case it will be defined to `0` – devnull69 Apr 12 '17 at 13:05
  • [Docs on hoisting](https://developer.mozilla.org/en-US/docs/Glossary/Hoisting) – Liam Apr 12 '17 at 13:05
  • @gurvinder372 you mean because it's inside the `$(function () {...` ? – blowz Apr 12 '17 at 13:06
  • Yes, javascript is a function scoped language and hoists variable declarations to the top of that scope – Liam Apr 12 '17 at 13:07
  • Omg... thanks guys... Didn't know that. But would it be fine if I'll remove the `var` inside the invoking function then? So to say: `if(typeof x == undefined) { x = 0; ... }` Correct? Thanks, @devnull69 – blowz Apr 12 '17 at 13:10
  • No because then your trying to set `0` to an undefined varaible. Like I said in my answer. What exactly are you trying to stop here? if you script runs on ready then `x` should always be defined in your example – Liam Apr 12 '17 at 13:22
  • @Liam yes, I am... but what's wrong with that? I mean if I detect that the variable isn't defined, I want to set it to `0`. That's the way I want it. Is this not "right" in terms of good coding or something? – blowz Apr 12 '17 at 13:26

1 Answers1

0

Because of variable hoisting in Javascript your script is ran as though it is:

$(function () {
  var x;
  if(typeof x == 'undefined') {
    x = 0;
    $("#dv").html(x);
  } else if (x == 5) {
    $("#dv").html(x);
  }
});

So x never equals undefined so it never sets it to 0. Note the variable x in your function is a different variable to the variable x in the page. This is because the variable in the script is closed over into the function scope.


If I'm understanding your problem correct I would do it this way:

<body data-x="5">
...
<div id="dv"></div>

$(function () {
  var x;
  if(typeof $('body').data('x') !== 'undefined') {

    $("#dv").html($('body').data('x'));
  } else {
    $("#dv").html(0);
  }
});
Community
  • 1
  • 1
Liam
  • 27,717
  • 28
  • 128
  • 190
  • Thanks. So what is the workaround of this - or this simply mean I won't be able to use the `x` of the `x = 5` inside of the invoking function? Because if I remove `var` from the invoking function, it does working – blowz Apr 12 '17 at 13:15
  • TBH what's your actual issue here? why would x not be defined? This whole thing is a bit of an [XY problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem) – Liam Apr 12 '17 at 13:16
  • hehe :) Well, I'm trying to manipulate the results upon the dynamic variable I'm getting. And then I want to check for the results. So, if I'm getting the `x = undefined`, I want to define it to `0`, if it's defined on the page as `x = 1`, I want to use `if else` statement to output some specific results. If it's `x = 2` exactly as with `x = 1`, but different output – blowz Apr 12 '17 at 13:20
  • but obviously the whole point here is to code right, in correct manner so to say :) So I'm not sure now, if I'm removing the `var` from the "scoped" invoked function, would I be doing right coding? – blowz Apr 12 '17 at 13:21
  • Because as far as I got it now, without the `var` inside the invoking fuction, it should look for outside for it, right? so it should be correct. Or I'm getting it wrong? – blowz Apr 12 '17 at 13:23
  • But if the var exists outside of it, why are you checking for undefined at all? It's **never** going to be undefined?! – Liam Apr 12 '17 at 13:39
  • It will, if the variable doesn't exist in the page file :) Variable is dynamic... It will be there only in some circumstances – blowz Apr 12 '17 at 14:22