JS/Javascript

[JS] 자바스크립트 스코프 ? : 변수의 유효 범위(2)

emayom 2021. 9. 1. 14:47
 

[JS] 자바스크립트 스코프 ? : 변수의 유효 범위

자바스크립트는 다른 프로그래밍 언어와는 다르게 전통적으로 함수 레벨 스코프를 지원하였고, 블록 스코프는 지원하지 않았다. ES6 이후부터 let, const가 등장하면서 블록 레벨의 스코프를 지원

emayom.tistory.com

 

이전에 var, let, const의 스코프에 대해 포스팅했었는데 

러닝 리액트 책을 보다가 var, let비교에 항상 보이는 예제가 있어 정리해보려고 한다!


 

var의 문제점

 

var로 변수를 사용할 경우 유의해야할 점이 있다.

  • 변수의 중복 선언 허용
  • 변수의 유효 범위(함수 레벨 스코프)

 

아래는 var를 사용했을 때 변수의 유효범위로 인해

예상치 못하게 작동할 수 있는 부분에 대해 잘 이해시켜주는 예제이다.

 

for문을 반복하며 생성한 div마다 onclick 핸들러를 할당하고,

클릭하면 몇 번째 박스인지를 알려주는 alert()문을 실행하도록 작성되었다.

 

이때 눈여겨봐야 할 부분은 반복문의 var로 선언된 i이다.

 

const container = document.getElementById("container");

for (var i = 0; i < 5; i++) {
  const div = document.createElement("div");
  div.onclick = function () {
    alert(`This is box #${i}`);
  };
  container.appendChild(div);
}

 

CSS를 적용해 코드를 실행해보면 기대와는 다르게

모든 div 박스가 클릭했을 때 'This is box #5'를 나타내는 것을 볼 수 있다.

이건 var만의 문제일까? let도 마찬가지일까?

 

const container = document.getElementById("container");

for (let i = 0; i < 5; i++) {
  const div = document.createElement("div");
  div.onclick = function () {
    alert(`This is box #${i}`);
  };
  container.appendChild(div);
}

 

같은 코드에서 i를 var 대신 let으로 선언해준 뒤 실행해보니 

박스가 생성된 순서대로 정상적으로 i가 출력되는 것을 확인할 수 있다.

 

 

이를 이해하기 위해서는 스코프 개념을 이해해야하는데

  • var는 함수 레벨의 스코프
  • let은 블록 단위의 스코프를 가진다.

 

var로 선언된 i 값은 for문이 종료되어도 함수가 종료되지않았기 때문에 유효하다. 

 

즉, 반복문에서 정의된 변수가 반복문이 종료되어도 남아있기 때문에 

i는 for문에서 i++가 된 상태로 종료되어버린 마지막 값을 보여주는 것이다.

 

 

+)

 

for문 자체를 즉시함수로 변경하면 문제가 해결될까? 안타깝게도 여기선 아니다 !

 

함수 외부에서 단순히 console.log(i)를 출력하려고하면 에러가 나겠지만,

얘는 onclick -> 콜백함수를 통해 함수가 종료되어도 i 에 접근할 수 있다. (클로저 문제)

ㅎㅎㅎㅎ 반복문에서 var 쓰지말자. 

 


⚠️ 아래 내용은 모두 개인적인 참고 / 기록을 위한 용도입니다. 참고해주시고 편안하게 봐주세요 :)  ⚠️
***    혹시라도 잘못된 정보가 있다면  언제든지 알려주시면 감사하겠습니다  !    ***