BDS Software

Exploring Javascript's setTimeout() Function

One debugging method that I find helpful is to compare buggy code, step-by-step, with similar code that is known to work.

For example, I wanted to use Javascript's setTimeout() function in an example, but it didn't seem to be working right.

This is the code I wrote first:

<button id="exec_button" class="button" onclick="test()">Click here</button><br><br>
<p id="First"></p><br>

<script>
function test() {
    setTimeout(external(), 3000);
}

function external() {
    document.getElementById("First").innerHTML = "Did this after 3 seconds?";
    document.getElementById("First").style.color = "#ff0000";
    document.getElementById("First").style.fontWeight = "bolder";
}
</script>

Try it:




As you can see, the code did the right thing, but it DIDN'T wait the three seconds to do it; it printed the message the instant you clicked the button. That's NOT what we want here.

to clear the message. Then go back to check the timing again by clicking the "Click Here" button again.


-----


So, I went to W3 Schools and used their sample code for comparison:

<p>Click the button to wait 3 seconds, then alert "Hello".></p>
<button class="button" onclick="myFunction()">Try it</button>

<script>
function myFunction() {
    setTimeout(function(){ alert("Hello"); }, 3000);
}
</script>

Click the button to wait 3 seconds, then alert "Hello".



Here, the 3 second delay is clear.


-----


So, I tried adjusting my code to use the example's anonymous function mechanism:

<button id="exec_button2" class="button" onclick="test2()">Click here 2</button><br><br>

<script>
function test2() {
    setTimeout(function(){ alert("mdjHello"); }, 3000);
}
</script>

Try this one:



So, this modification properly waits the 3 seconds before popping-up the "mdjHello" alert.

BUT, we don't want to just pop up an alert; we want to display some bold red text right in the page itself. We could continue to use an anonymous function, such as:

setTimeout(function(){
    document.getElementById("First").innerHTML = "Did this after 3 seconds.";
    document.getElementById("First").style.color = "#ff0000";
    document.getElementById("First").style.fontWeight = "bolder";
}, 3000);

But, I find this code to be obfuscated, confusing, and hard to follow. ( SIGH ! ). Probably just another manifestation of my advancing age.

Nevertheless, for purposes of this learning moment for you, and also to give me a fighting chance to understand what I'm looking at if I come back to this code next year ( or next WEEK ! ), I prefer to code in as clear and straightforward a manner as possible.

-----


Fortunately, the W3 Schools page also mentions that you can also use a "named" function instead of the previous example's anonymous function.

<p>Click the button to wait 3 seconds, then alert "Hello2".</p>
<button class="button" onclick="myFunction2()">Try it 2</button>

<script>
var myVar;

function myFunction2() {
    myVar = setTimeout(alertFunc, 3000);
}

function alertFunc() {
    alert("Hello2!");
}
</script>

Click the button to wait 3 seconds, then alert "Hello2".



This sample "named" function code also waits the proper 3 seconds before popping-up the alert.


-----


I notice that this example code declares a "myVar" variable and assigns the results of the setTimeout() function to that variable. Perhaps that's what I'm missing:

<button id="exec_button" class="button" onclick="test3()">Click here 3</button><br><br>
<p id="Second"></p><br>

<script>
var mdjVar;

function test3() {
    mdjVar = setTimeout(external3(), 3000);
}

function external3() {
    document.getElementById("Second").innerHTML = "Did this after 3 seconds too?";
    document.getElementById("Second").style.color = "#ff0000";
    document.getElementById("Second").style.fontWeight = "bolder";
}
</script>



But NO, as you can see, this code also doesn't wait the proper 3 seconds before displaying the message. It also displays the message instantly when you click the button.

to clear the message. Then go back to check the timing again by clicking the "Click Here 3" button again.

So adding the "mdjVar" variable is not the answer.

-----


But, as I continued to compare my buggy code with W3 School's working code, I noticed a tiny, but it turns out highly significant, difference -- an errant set of parentheses.

W3 School's code is:

setTimeout(alertFunc, 3000);

But my code is:

setTimeout(external3(), 3000);

If I eliminate those parentheses...... and use:

<button id="exec_button" class="button" onclick="test4()">Click here 4</button><br><br>
<p id="Third"></p><br>

<script>
function test4() {
    // NOT:
    //setTimeout(external4(), 3000);

    // But rather:
    setTimeout(external4, 3000);
}

function external4() {
    document.getElementById("Third").innerHTML = "Really did this after 3 seconds !!!";
    document.getElementById("Third").style.color = "#ff0000";
    document.getElementById("Third").style.fontWeight = "bolder";
}
</script>



to clear the message. Then go back to check the timing again by clicking the "Click Here 4" button again.


So removing those errant parentheses was INDEED the correct solution!

Upon further investigation, this appears to be a little-discussed (at least in my experience) feature of Javascript Functions. W3 Schools says:

A JavaScript function is defined with the function keyword, followed by a name, followed by parentheses ()....

Example

Convert Fahrenheit to Celsius:

function toCelsius(fahrenheit) {
    return (5/9) * (fahrenheit-32);
}
document.getElementById("demo").innerHTML = toCelsius(77);

The () Operator Invokes the Function

Using the example above, toCelsius refers to the function object, and toCelsius() refers to the function result.

Accessing a function without () will return the function definition instead of the function result...

However, this () operator does not appear in W3 Schools' Javascript Operators Reference, nor in Mozilla's MDN Web Docs' Expressions and Operators List.

If you're interested in going into the () operator in more depth, you might check out Stackoverflow's discussion (listed in the References below). One instructive example they provide is:

function foo() {
    return 2;
}

typeof foo()
= "number"

typeof foo
= "function"


                                                                                                                                                                M.D.J. 2018/07/25


----------

References:

Mozilla. MDN Web Docs' Expressions and Operators List. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Expressions_and_Operators.

Stackoverflow. Javascript () Operator. https://stackoverflow.com/questions/3955110/javascript-operator-invokes-function.

W3 Schools. Javascript Functions. https://www.w3schools.com/js/js_functions.asp.

W3 Schools. Javascript Operators Reference. https://www.w3schools.com/jsref/jsref_operators.asp.

W3 Schools. setTimeOut(). https://www.w3schools.com/jsref/met_win_settimeout.asp.