[js] var / let

ppparkta·2022년 10월 11일
1

웹개발

목록 보기
1/26
post-thumbnail

var와 let

최근에 자바스크립트를 공부하고 있는데 const를 변수처럼 사용하는 방식이 너무 낯설어서 정리하게 됐습니다. const를 정리하기 전 var와 let의 차이점, 동기 비동기에 대해 설명하도록 하겠습니다.

var와 let

var는 let이 만들어지기 전부터 존재했던 자료형입니다. 박힌 돌이 있는데도 let이 새롭게 나온데에는 이유가 있었습니다. var는 어딘가 나사빠진 기능을 갖고있기 때문 (...)

var

  • 예약어와 같은 이름으로 변수 생성 가능
  • 재선언(!!) 가능(재할당이 아닙니다. 재선언 입니다)

var와 let은 스코프에 대한 기준도 다릅니다. 따라서 비동기 처리에 주의해야 해요. 이 내용은 뒤에 서술하겠습니다.

스코프

스코프는 단어 그대로 범위(scope)를 의미합니다. 저는 더 쉽게 변수가 살아있는 공간이라고 이해했습니다.

아래의 코드에서 출력되는 값은 무엇일까요?

arr = [1, 2, 3];
for (let i = 0; i < 3; i++) {
	setTimeout(() =>{
		console.log(arr[i])}, 500 * (1 + i));
}

당장 개발자 도구를 눌러서 확인해보겠습니다. 순서대로 1 - 2 - 3이 출력됩니다. 그렇다면 let을 var로 바꾸면 어떻게 될까요?

arr = [1, 2, 3];
for (var i = 0; i < 3; i++) {
	setTimeout(() =>{
		console.log(arr[i])}, 500 * (1 + i));
}

콘솔에는 undefined가 세번 출력되었습니다. 둘 다 같은 기능을 하는 자료형인데 왜 출력 결과에 차이가 있을까요?

그 이유가 스코프에 있습니다. var는 함수 스코프를 따르고 있기 때문입니다. 즉 변수가 살아있는 공간이 함수이기 때문입니다.

위의 코드에서 i는 중괄호({})로 묶인 반복문에서 벗어났을 때 생명을 잃지 않습니다. 블록 스코프가 아닌 함수 스코프를 따르기 때문입니다. 말 그대로 함수를 벗어나지 않는 한 변수는 기능을 유지합니다.

그러나 의문이 있을것입니다.

동기와 비동기

앞서 설명한 이유를 듣더라도 콘솔이 arr[i]undefined 로 읽는 것은 쉽게 이해되지 않습니다. 이는 반복문 안에 들어있는 setTimeout 과 연관이 있습니다.

setTimeout 함수는 코드가 적힌 순서와 실제 실행순서가 다른 비동기 함수입니다. (자세한 이유가 궁금하다면 이 문서를 참조해주세요)

동기, 비동기 함수가 무엇일까요? 이미 앞에서 답이 나왔습니다. 웹에 대해서 살펴봅시다.

이 그림에서 client와 server는 request와 response로 상호작용하고 있습니다. 우리는 요청(request)와 응답(response)에 집중하면 됩니다.

동기는 요청이 있을 때 바로 응답하는 것을 의미합니다. 어떤 요청을 쌓아놓고 본인이 원하는대로 처리하는 것이 아닌 즉문즉답하는 것입니다.

그럼 비동기는 무엇일까요?

동기의 반대입니다. 요청이 있을 때 바로 응답하지 않아도 됩니다. 어떤 요청을 쌓아놓고 내가 원하는 때에 원하는 순서대로 처리하는 것. 그것이 비동기입니다.

비동기와 var

앞서 드린 설명이 잘 와닿지 않아도 괜찮습니다. 비동기를 프로그래밍에 대입했을 때, 내가 작성한 코드가 순서대로 작동하지 않고 원하는 동작을 먼저 처리한 뒤에 작동하면 그것이 비동기입니다.

자바스크립트에서는 대표적으로 addEventListner함수가 있습니다. 다시 한번 코드를 봐볼까요?

arr = [1, 2, 3];
for (var i = 0; i < 3; i++) {
	setTimeout(() =>{
		console.log(arr[i])}, 500 * (1 + i));
}

setTimeout 함수는 비동기 함수라서 브라우저 상황에 따라 실행 순서가 뒤로 밀릴 수 있습니다. 브라우저 상황이 나빠서 setTimeout함수가 실행되기 전에 for문이 먼저 실행되었다면 어떻게 됐을까요?

for문이 모든 반복을 끝냈을 때 i의 값은? 블록 스코프를 따르는 경우 i는 반복이 끝난 순간 없는 변수라고 봐야합니다. 그러나 var가 함수 스코프를 따른다는 것을 아까 설명드렸죠?

for문이 모든 반복을 끝냈을 때 후위증가하므로 i의 값은 3입니다.

이제 모든 의문이 풀렸습니다. 앞서 변수를 let이 아닌 var로 바꿨을 때 콘솔이 undefined를 나타내던 이유는 arr[i] (= arr[3]) 이 없는 인덱스를 참조했기 때문입니다. 이미 모든 반복을 끝낸 i 는 3이라는 값으로 고정돼 있습니다. 따라서 undefined가 연속으로 출력된 것이죠.

var와 비동기함수를 함께 썼을 때 생길 수 있는 문제, 예약어 중복, 재선언 미방지 등 다양한 이유로 인해 이제 var보다는 let을 사용하는 것이 권장되는 것입니다.

profile
겉촉속촉

0개의 댓글