-4

I have the following Javascript code attached to an HTML document with some CSS styling.

It is simply a box on the screen that changes the style background property colour according to those seen in the array. The id of "colour-changer" is used to access the HTML document and changes it each time the array is iterated.

The function declaration changeColour(); is used to make this happen by using colours.length to count its way through the array and then puts the array value into the HTML, which changes its background colour every 3 seconds.

Once it comes to the end of the array the counter is reset to 0, and it continues around again.

The setInterval method invokes the callback method changeColour() every 3 seconds to make this happen.

In order to stop the cycle, an onclick is event is added which invokes a clearInterval() method to print out "Timer stopped" inside the box. In order to do this the setInterval() method had to be stored in variable myTimer.

See the code below. It all works fine but this is not my real problem.

let colourChanger = document.getElementById ("colour-changer");
let colours = ["red","blue","green","pink"];
let counter = 0;

function changeColour(){

  if (counter >= colours.length){
   counter = 0;
  }
  
  colourChanger.style.background = colours[counter];
  counter++;

}

let myTimer = setInterval(changeColour, 3000);

colourChanger.onclick = function (){
  
  clearInterval(myTimer);
  colourChanger.innerHTML = "Timer stopped";

}

What I cannot understand is the line let myTimer = setInterval(changeColour, 3000);

From my understanding if you store a function inside of a variable, it will NOT execute unless called separately. It will just sit there stored in the variable myTimer.

There is no setInterval(); call made outside of the variable anywhere.

MY QUESTION:

How then is this method invoked since it is simply stored inside of the variable myTimer?

martin958
  • 1
  • 2
  • The method is not stored inside the variable. The return of that method is; in this case, `setInterval` returns a numerical identifier for that interval, which can then be used to clear that interval(which is done in the onclick). This could be realized by simply reading [the documentation](https://developer.mozilla.org/en-US/docs/Web/API/setInterval). – Daedalus Dec 02 '21 at 11:32
  • [setInterval](https://developer.mozilla.org/en-US/docs/Web/API/setInterval) *This method returns an interval ID which uniquely identifies the interval* – freedomn-m Dec 02 '21 at 11:32
  • 2
    At least related? [*What is the difference between a function call and function reference?*](https://stackoverflow.com/questions/15886272/what-is-the-difference-between-a-function-call-and-function-reference) – T.J. Crowder Dec 02 '21 at 11:37
  • As a final question. Is ```let myTimer = setInterval(changeColour, 3000);``` still a function expression? Or is it classed as something else? – martin958 Dec 02 '21 at 17:32

3 Answers3

2

No, your understanding is wrong.

It executes setInterval(changeColour, 3000); and stores this particular interval reference ID to myTimer to later be used in clearInterval(myTimer)

var myTimer = setInterval(() => console.log('ping'), 3000);

setTimeout(() => clearInterval(myTimer), 10000);

console.log('myTimer value: ', myTimer);
Justinas
  • 41,402
  • 5
  • 66
  • 96
  • So ```clearInterval(myTimer)``` has invoked it? If so, why does it still run even though the onclick event does not happen? – martin958 Dec 02 '21 at 11:34
  • @martin958 - No, `setInterval` is called by the first line of code in the snippet, and its return value is stored in `myTimer`. `clearInterval(myTimer)` cancels the interval timer that was started by calling `setInterval`. – T.J. Crowder Dec 02 '21 at 11:35
  • You mean ```setInterval``` is called by this line ```let colourChanger = document.getElementById ("colour-changer");``` ? – martin958 Dec 02 '21 at 11:38
  • @martin958 No. `setInterval` is called by the line that sets the variable `myTimer`. – Daedalus Dec 02 '21 at 11:39
1

setInterval() function will return IntervalID, It will set execution interval for given milliseconds.

In your case once this line is executed it will start executing changeColour function every 3000ms / 3 seconds and return IntervalID.

Now this IntervalID is used to stop executing your function every 3 seconds in the future.

to stop executing you can use clearInterval(IntervalID).

if any doubts please comment.

freedomn-m
  • 27,664
  • 8
  • 35
  • 57
Hardik Satasiya
  • 9,547
  • 3
  • 22
  • 40
  • yes because the function was assigned to `f` as it was function declaration, but `setInterval` It itself is a function call `setInterval(changeColour, 3000);` you are calling `setInterval` function and not declaring it so it executed inline and return ID. – Hardik Satasiya Dec 02 '21 at 11:54
  • Why is setInterval a function call when let f = function foo(){console.log("Hello");}; is only a declaration? – martin958 Dec 02 '21 at 12:01
  • @martin958 because in `f=function foo(){ }` you have the *keyword* `function` which says "this is declaring a function" – freedomn-m Dec 02 '21 at 12:08
  • So let f=foo () { } will be invoked if the function keyword is left out? – martin958 Dec 02 '21 at 12:13
  • No, that will give a `unexpected token` error (ie a syntax error). And if you make it `let f = foo();` then it will give `foo is not defined` – freedomn-m Dec 02 '21 at 12:14
  • And why should ```let f = foo();``` not call the foo function? Presuming the function foo was already declared elsewhere? – martin958 Dec 02 '21 at 12:21
  • Yes, it would *if* it was previously defined. `let f=foo;` would *not* call it, but you could do `f();` later which is the similar scenario to `f=function foo(){}` but with a predefined function `foo` – freedomn-m Dec 02 '21 at 12:23
1

In order to do this the setInterval() method had to be stored in variable myTimer.

No, the return value of setInterval is stored in myTimer by that code. setInterval is called (it has (/*...*/) after it, which calls it).

From my understanding if you store a function inside of a variable, it will NOT execute unless called separately.

That's correct, but that's not what that line of code is doing. This code:

let myTimer = setInterval(changeColour, 3000);

calls setInterval and stores its return value in myTimer, exactly the way:

let x = example();

calls example and stores its return value in x.

It's the changeColour function that is only referenced, not called, by that code (there's no (/*...*/) after it). Doing that passes changeColour into setInterval, so that setInterval knows what function to call every three seconds or so.

So in that code, setInterval is called, and changeColour is just referenced (it's called later by the timer mechanism).

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875