0

I'm new to JS, and I don't understand why this doesn't work. The following is in a file called test1.js

var greeting;

function randomGreeting(){
    var greet = new Array("BORING JS TEST ALERT", "EXCITING JS TEST ALERT", "AWESOME JS TEST ALERT");
    var randGreet = Math.floor(Math.random() * greet.length);

    greeting = {
        alert: greet[randGreet]
    };
}

In a separate test2.js file:

alert(greeting.alert);

In my HTML I have randomGreeting() being called in the body's onLoad, and I have test1.js loaded before test2.js, but I still get undefined from the console when test2 is ran. Why?

4
  • 4
    When is randomGreeting called? Commented Jul 5, 2016 at 19:35
  • Whoops, sorry. randomGreeting is called in the body's onLoad. Commented Jul 5, 2016 at 19:36
  • 1
    But alert(greeting.alert) is not in onload? That means it runs before randomGreeting. Commented Jul 5, 2016 at 19:37
  • 2
    Yea I'd post more of your code. Sounds like alert() runs before the onload event handler.. Commented Jul 5, 2016 at 19:37

2 Answers 2

1

you have a race condition against test2.js running and the document onload event which fires much later.

You either delay the alert until the variable is set

(function(){
   if (typeof greeting == "undefined")
      return window.setTimeout(arguments.callee, 10);

   alert(greeting.alert);
}());

if you're not recalling randomGreeting, you can just inline it

var greet = new Array("BORING JS TEST ALERT", "EXCITING JS TEST ALERT", "AWESOME JS TEST ALERT");
var randGreet = Math.floor(Math.random() * greet.length);
var greeting = {
    alert: greet[randGreet]
};

Or you can change the scripts to use the defer attribute

<script scr="test1.js"></script>
<script scr="test2.js" defer></script>
<script>
window.onload = function(){
    alert(greeting.alert);
};
</script>
Sign up to request clarification or add additional context in comments.

1 Comment

I guess this really highlights the fact that I need to better understand the execution order of scripts and event listeners. If you have a good reference to help me better understand that, I'd appreciate it.
0

Use Immediate Invoking Function:

You could wrap your randomGreeting() in an immediate invoking function code block to get it executed as soon as it's declared and thus your code will work:

var greeting;

(function randomGreeting(){
    var greet = new Array("BORING JS TEST ALERT", "EXCITING JS TEST ALERT", "AWESOME JS TEST ALERT");
    var randGreet = Math.floor(Math.random() * greet.length);

    greeting = {
        alert: greet[randGreet]
    };
})();

In a separate test2.js file:

alert(greeting.alert);

Comments

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.