1

This was an embarrassing question about something I thought I fully understood about global variable scope. I'm re-editing it, despite knowing the answer now, because it might save someone else a LOT of grief. Originally I had a variable declared on a page, that wasn't being "seen" in a linked .JS file, thus over complicating the situation. Now, however, I see how the problem can be reproduced very simply. Here is some example code illustrating the problem.

script> 
var myGlobalVar = 100;

function testMyVar() {
    if (typeof myGlobalVar == "undefined") var myGlobalVar = 200;
    alert ("var is now: " + myGlobalVar)
    }
</script>

Now lets say you call the function, maybe from an onclick event of a button like this...

<button onclick="testMyVar()">TestVar</button>

Imagine my surprise when the "alert()" function displayed "200"! Why? Again the original case where I first observed this behavior was when the function was in in a linked "JS" file. The idea was to allow me to detect whether the variable had been declared in the page. If it had not been declared, I would declare it and give it a 'default' value. But now, having reproduced the issue in the simple demo above, I see it does not matter whether the function is in a JS file or not.

So why did it appear as if "myGlobalVar" was being detected as undefined? The answer, which i now know, came when I modified my function code like this...

  script> 
    var myGlobalVar = 100;

    function testMyVar() {
        var myLocalVariable = 200;
        if (typeof myGlobalVar !== "undefined") myLocalVariable =myGlobalVar;
        alert ("var is now: " + myLocalVariable)
        }
    </script>

Now, when the function is called, the expected value "100" is displayed. And if the line declaring "myGlobalVar" is removed, the same function now properly detects that it doesn't exist, and uses my default value "200"

Having seen this, it seems to me this is probably the best example of how variable "hoisting" can come back to make you think you're going insane! In the original function it may appear that I am declaring and assigning a value to "myGlobalVar" only after I have tested and proven that it doesn't exist. But that is NOT what is happening! This must be the result of variable "hoisting" behavior of javascript, which caused the variable declaration and definition (200) to actually occur before the test, rather than the sequential manner in which the code makes it appear.

So now I know I can NOT declare a variable within a function using the same name as a global, if I have any intention of testing for the global version. Because no matter where in the function I declare a variable, its actually going to me moved (hoisted) to the top of the function. So if it has the same name as the global, its going to replace the global before I can test it!

To turn this into a question, as that's what this forum is for, I'll just ask: Am I correct now in my understanding of seemingly strange behavior of the first example?

8
  • Are you sure the variable isn't set to the string "undefined"? Commented Oct 12, 2020 at 20:51
  • There's not enough detail here to diagnose the problem. I'm not even 100% sure I precisely understand everything you're saying. But I will ask: what happens if you put a breakpoint in your code at the start of the dimBackground function? What is the value of dimColor before the if statement? What is it afterward? Note also that your guard here just creates a new local variable within that function whose value is '#003333', so dimColor elsewhere (outside the function) could well still be undefined. Commented Oct 12, 2020 at 21:00
  • information is missing : 1 - is all of this only in the <head> part or is it also distributed in the <body> part? 2 - you do not give any indication on the order of presence of your different scripts Commented Oct 12, 2020 at 21:06
  • I concur with Robin and MisterJojo - there is not enough info. Commented Oct 12, 2020 at 21:49
  • @VLAZ - Yes I'm suer. But even if that were not the case, I've tried simply putting "alert(dimColor)" as the first line within the function, and the alert box message just says "undefined" Commented Oct 12, 2020 at 21:53

1 Answer 1

2

Using window.dimColor is actually OK, because that's the only way to create a global variable when you're inside a function.

In this kind of case I would just use if (dimColor) to see if the global variable exists:

function checkColor(){
   // check if there's a global dimColor
   if(dimColor) {
      console.log("there's already a color defined");
   } else {
      // create the global dimColor
      window.dimColor = "#FF0000";
   }
}

You can write this shorter!

function checkColor(){
    window.dimColor = dimColor || "#FF0000";
}
Sign up to request clarification or add additional context in comments.

7 Comments

But the bottom line is that if I strip away everything in the function except "alert(dimColor)", I would expect to see something other than an alert box saying "undefined". I've tried every logical construct including just "if (variable). And it doesn't exist. And, I wouldn't expect a var declaration outside of any function to NOT be global, which seems to be the case here.
Its a shame my question was closed because in my last edit I revealed a major clue to what was happening., a clue that might help another coder too. Since its solved now, it doesn't make sense for me to re-post the question, and I certainly made the original problem easy enough, that I honestly could not have made is simpler. But in any case, yes... I appreciate knowing that forcing a global via 'window.varName is not a terrible thing to do.
You could reopen the question if you can provide a situation where others also see the bug you are mentioning. From your current code, it's not clear what's going wrong.
@Kokododo I would like to re-open it, because I now understand the problem, can demonstrate it in less than 5 lines of code, and seriously believe what I've learned could help others, Even if it was stupid mistake on my part, the fact I've been coding in JavaScript for many years and still got fooled tells me others could benefit from what I've learned. But the problem now is that this is not a forum of riddles. As I understand the stackexchange forums, you're not supposed to post questions you know the answer too, right? , So please advise.
It’s ok to answer your own question, but in this case the problem is not reproducible from the code that you posted. It seems that something external is causing your problem- I think that’s why they closed the question.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.