이전에 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 쓰지말자.
⚠️ 아래 내용은 모두 개인적인 참고 / 기록을 위한 용도입니다. 참고해주시고 편안하게 봐주세요 :) ⚠️
*** 혹시라도 잘못된 정보가 있다면 언제든지 알려주시면 감사하겠습니다 ! ***
'JS > Javascript' 카테고리의 다른 글
[JS] 자바스크립트 함수 : 함수 선언식 vs 함수 표현식 ? (0) | 2021.09.05 |
---|---|
[JS] 자바스크립트 <input> : id와 name (0) | 2021.09.03 |
[Javascript] ES6 배열 메소드 : Array.from() (0) | 2021.08.23 |
[Javascript] 이벤트 : onclick() ? addEventListener() ? (0) | 2021.08.21 |
[JS] querySelector , querySelectorAll ? (0) | 2021.08.05 |