본문으로 건너뛰기
기술스택 · stack/javascript/let과 const로 값에 이름 붙이기

JavaScript · 2장 기본

let과 const로 값에 이름 붙이기

프로그램은 값을 기억해 두었다가 다시 꺼내 써요. 값에 이름을 붙이는 방법인 let과 const, 그리고 둘 중 무엇을 언제 쓰는지, 이름은 어떻게 짓는지 정리했어요.

#2.2

01. 값에 이름표 붙이기

변수는 값에 붙인 이름표예요. 이름표를 만드는 키워드는 두 가지예요. 나중에 다른 값을 가리키게 바꿀 수 있는 let, 한 번 붙이면 바꿀 수 없는 const예요.

let cartCount = 0;          // 바뀔 값
cartCount = cartCount + 1;

const shippingFee = 3000;   // 바뀌지 않을 값

console.log(cartCount, shippingFee); // 1 3000

=은 "같다"가 아니라 오른쪽 값을 왼쪽 이름에 넣는다는 뜻이에요. 그래서 cartCount = cartCount + 1은 "지금 값에 1을 더해서 다시 넣는다"로 읽어요. 이름을 처음 만들 때만 let · const를 붙이고, 그 뒤로는 이름만 써요.

옛 코드에서는 var도 보여요. var는 아래에서 볼 보호 장치가 없어서 새 코드에서는 쓰지 않아요. 왜 그런지는 6장 var 글에서 자세히 다뤄요.

02. const는 "다시 가리키기"만 막아요

const를 "값을 못 바꾸는 변수"로 오해하기 쉬워요. 정확히는 이름표가 다른 값을 가리키지 못하게 막는 거예요. 이름표가 가리키는 배열이나 객체의 안쪽은 얼마든지 바뀔 수 있어요.

①let count는 0을 가리키다 1로 옮겨 가요. const cart가 가리키는 배열에는 '공책'이 더해지지만, cart를 새 배열 ['지우개']로 옮기려 하면 TypeError로 막혀요.
const cart = ['연필'];
cart.push('공책');       // 안쪽 바꾸기: 돼요
console.log(cart);       // ['연필', '공책']

cart = ['지우개'];       // 다른 배열을 가리키기: 안 돼요

배열 · 객체의 안쪽까지 못 바꾸게 하려면 Object.freeze 같은 다른 도구가 필요해요(7장). 반대로 말하면, const로 만든 배열에 값을 더하는 건 전혀 문제가 아니에요.

03. 선언 전에 쓰거나 두 번 선언하면

let · const로 만든 이름은 선언한 줄보다 앞에서 쓰면 오류가 나요. 값이 아직 준비되지 않았다는 뜻이에요.

console.log(total);
let total = 100;

같은 범위에서 같은 이름을 두 번 선언해도 오류예요. 이건 문법 오류라서, 코드를 실행하기 전에 걸리고 한 줄도 실행되지 않아요.

console.log('시작');
let user = '하늘';
let user = '바다';

이름은 자기가 선언된 중괄호 { } 안에서만 살아 있어요. 그래서 다른 블록에서는 같은 이름을 새로 만들 수 있어요. 이 범위(스코프)는 6장 클로저에서 다시 자세히 봐요.

const message = '바깥';
{
  const message = '블록 안';
  console.log(message); // 블록 안
}
console.log(message);   // 바깥

04. 이름 짓기

이름에는 글자 · 숫자 · $ · _를 쓸 수 있어요. 숫자로 시작할 수 없고, 대소문자를 구분해요(total과 Total은 다른 이름). let · class · return처럼 언어가 쓰는 단어(예약어)는 이름이 될 수 없어요. 한글 이름도 문법상 되지만, 팀 작업과 검색을 생각해 영어로 지어요.

규칙보다 중요한 건 읽는 사람이 바로 알아보는 이름이에요. 실무에서 많이 쓰는 관례는 이래요.

관례예쓰는 곳
camelCasecartCount, getUser변수 · 함수 (기본)
PascalCaseShoppingCart클래스 (9장)
UPPER_SNAKE_CASEMAX_RETRY, API_URL실행 전에 정해지는 설정값
is · has · can으로 시작isLoggedIn, hasCoupon참 · 거짓 값
복수형users, prices배열
단위를 이름에timeoutMs, priceWon시간 · 돈 · 크기

data, temp, a, value2 같은 이름은 무엇이 들었는지 알려 주지 않아요. 한 글자 이름은 for (let i = 0; …)처럼 아주 짧은 반복의 번호 정도에만 써요.

아래 코드는 문구점 주문 금액을 계산해요. 동작은 그대로 두고, 무슨 값인지 알 수 있게 이름만 바꿔 보세요. 바뀌지 않는 값은 const로 바꿔요.

let a = 3;
let b = 1500;
let c = a * b;
console.log(c); // 4500
해답 보기

한 예예요. 세 값 모두 다시 넣는 일이 없어서 const가 맞아요. 단위를 이름에 넣으면 금액이 원 단위라는 것도 드러나요.

const quantity = 3;
const unitPriceWon = 1500;
const totalWon = quantity * unitPriceWon;
console.log(totalWon); // 4500

모든 변수를 let으로 만든 코드예요. const로 바꿀 수 있는 것은 모두 바꾸고, 바꿀 수 없는 것만 let으로 남겨 보세요. 실행해서 결과(22000)가 그대로인지 확인해요.

let taxRate = 0.1;
let prices = [12000, 8000];
let total = 0;
for (let price of prices) {
  total += price;
}
let tax = total * taxRate;
console.log(total + tax);
해답 보기

total만 반복하면서 다시 값을 넣으니 let으로 남아요. prices는 배열 안쪽도 바꾸지 않지만, 바꾸더라도 다른 배열을 가리키지만 않으면 const로 충분해요. for (const price of prices)도 돼요 — 반복할 때마다 새 이름이 만들어지기 때문이에요.

const taxRate = 0.1;
const prices = [12000, 8000];
let total = 0;
for (const price of prices) {
  total += price;
}
const tax = total * taxRate;
console.log(total + tax); // 22000

05. 실전 포인트

  • 언제 쓰나요? 기본은 const예요. 값을 다시 넣어야 할 때(반복하며 더하기, 상태가 바뀌는 값)만 let을 써요. 이렇게 하면 "let이 보이면 이 값은 바뀐다"는 신호가 돼서 코드 읽기가 쉬워져요.
  • 대신 쓰는 것: var는 쓰지 않아요. ESLint의 prefer-const · no-var 규칙(3장)을 켜 두면 도구가 알려 줘요.
  • 흔한 실수: const 배열에 push가 되는 걸 보고 놀라거나, 반대로 const면 안쪽도 안전하다고 믿는 것. 그리고 바깥 이름과 같은 이름을 블록 안에서 다시 만들어(가리기) 어느 값을 쓰는지 헷갈리는 것이에요.

정리

  • 변수는 값에 붙인 이름표예요. let은 다시 가리킬 수 있고, const는 못 해요.
  • const는 이름표만 고정해요. 가리키는 배열 · 객체의 안쪽은 바뀔 수 있어요.
  • 선언 전에 쓰면 ReferenceError, 같은 범위에서 두 번 선언하면 SyntaxError예요.
  • 기본은 const, 필요할 때만 let, var는 쓰지 않아요. 이름은 무엇이 들었는지 보이게 지어요.
SIMPLE · 기술스택 / JavaScript — 2장 기본