질문드립니다 .

var i;
for(var i=5;i>=0;i–)
{
setTimeout(function(){
console.log(i===0 ? “GO” :i);
},(5-i)*1000);
}

위의 예제는 처음 i가 5일때 진입을 하면
setTimeout(function(){
console.log(i===0 ? “GO” :i);
},0);

처음에 5는 찍히고 그다음부터 setTimeout이니깐 1초뒤 ,2초뒤에 함수가 실행된다고 봤을때 이미 포문은 돌고 난뒤니깐 맨처음에 5일때 타임아웃 간격이 0 이니깐 바로 5가 콘솔에 찍히고
포문 다도는 시간이 타임아웃보다 빠르니깐 i가 0일떄(마지막일떄 ) "GO"로
5일떄 "GO"로 2번 찍히지 않을까요??
근데 답은 주기적으로 -1만 찍네요 이거 설명좀 부탁드려도 될까요 ???

그 현상은 두 가지의 개념을 알고 있어야 이해가 가능합니다.

  • 비동기
  • 스코프

setTimeout에 넘기는 함수는 비동기 작업으로,
메인코드가 모두 실행된 이 후에 실행되게 됩니다.

관련 용어를 언급하여 설명드리면 setTimeout 으로 넘긴 함수는
이벤트 루프가 감시중인 호출 스택(콜 스택) 이 비워져 있을 때 실행됩니다.

그리고 자바스크립트의 스코프(전역/지역/블락) 에 대해서 좀 더 알아보실 필요가 있습니다.
질문자님의 코드에서 i는 블락 스코프가 적용되지 않습니다.

이 두 현상이 겹쳐서 만들어낸 현상이며 자세하게는 아래와 같습니다.

  1. var로 선언된 i 값은 for문에 의해 모두 감소된 값인 -1값을 가지게 됩니다.
    1.1 각 for문에서 setTimeout으로 넘기는 함수는 for문이 끝나기 전에는 절대 실행되지 않습니다.
  2. setTimeout으로 넘긴 함수들은 지정한 타임아웃 값에 의해 만료될 때를 기다립니다.
    2.1 다른 쓰레드에서 처리되고 난 후, 이벤트 큐(작업 큐) 에서 대기중인 메시지가 있으며
    2.2 자바스크립트 호출 스택이 비어있는지 이벤트 루프에서 지속적으로 확인합니다.
  3. 메인 코드가 모두 실행이 끝나면 setTimeout으로 넘겼던 함수들 중 타임 아웃 된 함수가 순차적으로 실행될 것입니다.
  4. 각 함수에서는 i값을 콘솔 로그로 뿌리게 되는데 이미 앞서 실행된 코드에서 -1을 할당했으므로 모두 -1을 출력하게 됩니다.

for문 안에서 감소하는 i 값을 유지시키는 가장 간단한 방법은

for (let i = 5; i >= 0 ;i--) {
  setTimeout(function(){
    console.log(i === 0 ? "GO" : i);
  }, (5 - i) * 1000);
}

varlet으로 변경하는 것입니다. 블락 스코프가 적용되면서 의도한대로 동작합니다.
(letconst는 자바스크립트 코드의 부작용을 줄여주므로 대부분의 경우 사용하면 좋습니다.)

IIFE로 스코프를 강제하는 방식도 있습니다. 이건 직접 만들어 보세요.

위에 굵은 글씨로 언급한 용어들은 구글링 해 보시면 관련 문서들이 많이 나옵니다.
그 뜻과 의미를 찾아 보시면 자바스크립트의 동작을 이해하시는데 도움이 될 겁니다.