변수와 상수
변수 선언 키워드 비교
구분 | 재선언 가능 | 재할당 가능 | 스코프 | 호이스팅 | TDZ 존재 |
---|---|---|---|---|---|
var | 가능 | 가능 | 함수 스코프 | O | X |
let | 불가능 | 가능 | 블록 스코프 | O | O |
const | 불가능 | 불가능 | 블록 스코프 | O | O |
변수 (Variable)
js
let 변수의이름 = 변수에 저장할 값;
- 데이터를 저장할 수 있는, 이름을 가진 저장소
- 변수에 저장된 값은 나중에 꺼내거나, 변경할 수 있다.
- 변수명은 값의 의미나 역할을 잘 나타내도록 짓는 것이 바람직하다.
변수 선언
js
let color = "skyblue";
console.log(color); //skyblue
- color라는 변수를 선언하고, "skyblue"라는 문자열 값을 할당한 것
- 값을 할당할 때는 할당 연산자
=
을 사용하는데 수학의 "같다"가 아닌, 값을 변수에 넣는다는 의미의 대입 연산자이다.
변수 재할당
js
let color = "skyblue";
color = "yellow"; // 재할당
console.log(color); // yellow
- 변수는 선언한 이후에도 값을 바꿀 수 있다.
- 이처럼 기존에 저장된 값을 새로운 값으로 재할당할 수 있다.
변수 명명 규칙 (Variable Naming Rules)
- 변수명에는 ‘$’와 ‘_’를 제외한 기호는 사용 불가
js
let $name;
let test_data;
- 변수명의 맨 앞에는 숫자 사용 불가 (맨 뒤에는 숫자 사용가능)
js
let 9test; // 불가능
let test99; // 가능
- 자바스크립트의 예약어 사용 불가
js
let let = ""; // 에러
let class = "abc" // 에러
- 카멜케이스(camelCase)
js
let userName;
let totalPrice;
let isAvailable;
- 가독성을 높이기 위한 변수/함수 표기법
- 띄어쓸 수 없기 때문에 첫 단어는 소문자, 그 다음 단어부터는 첫 글자 대문자로 작성
자바스크립트 변수 선언의 특징
C와 Java의 변수 선언
js
char color[10] = “skyblue”; // C
string color = “skyblue” // Java
- C나 Java에서는 변수를 선언할 때 해당 변수의 자료형을 먼저 작성한 후 변수명을 작성한다. char나 String과 같은 자료형을 앞에 작성하여 변수의 데이터 타입이 고정된다. 다른 자료형을 넣으면 컴파일 에러가 발생한다.
자바스크립트의 변수 선언
js
let color;
color = “skyblue”;
- 자바스크립트는 변수를 선언할 때 자료형을 명시하지 않는다.
- 변수에 저장된 값에 따라 자료형이 자동으로 결정되며, 이를 동적 타입 (Dynamic Typing)이라고 한다.
변수의 자료형 확인 방법
js
let nowType = “안녕하세요”;
console.log(typeof nowType); // "string"
typeof
연산자를 사용해 변수의 현재 자료형을 확인할 수 있다.
자료형은 어떻게 바뀔까?
js
let nowType = “안녕하세요”;
console.log(typeof nowType); // "string"
nowType = 100;
console.log(typeof nowType); // "number"
- 자바스크립트는 동적 타입 언어이기 때문에, 같은 변수에 서로 다른 타입의 값을 할당해도 에러 없이 동작한다.
- 변수에 저장된 값이 바뀌면, 변수의 자료형도 그에 맞게 자동으로 바뀐다.
상수 (Constant)
js
const PI = 3.14;
console.log(PI); // 3.14
PI = 3.14159; // 오류! 상수는 값을 변경할 수 없다.
- 한 번 값이 할당되면 변경할 수 없는 변수이다. (불변성 보장)
- 자바스크립트에서는
const
키워드를 사용해 상수를 선언한다. - 상수를 선언할 때 반드시 초기값을 함께 할당해야 한다.
상수를 사용하는 이유
- 변경되지 않아야 하는 값을 안전하게 저장하기 위해 사용 (변경 방지)
js
const birth = "04-07";
const name = "hyebin";
- 기억하기 쉽게 만들기 위해
js
const PI = 3.14159;
const API_URL = "https://api.example.com";
const GITHUB_URL = "http://github.com/miloupark";
let userUrl = GITHUB_URL; // 상수값을 다른 변수에 할당 가능
- 상수는 값이 변경되지 않기 때문에, 복잡하거나 자주 쓰는 값을 기억하기 쉽게 저장하는 별칭(alias) 역할을 하며, 보통 모두 대문자로 작성하는 네이밍 컨벤션을 따른다.
var
var 키워드 사용하지 않는 이유
var
는 ES6 이전에 사용되던 변수 선언 방식으로, 몇 가지 예상치 못한 문제를 일으킬 수 있어 현재는 잘 사용하지 않는다. 특히 let, const에 비해 예측 가능한 코드 작성이 어렵고, 오류 발생 가능성이 크다.
1. 변수의 중복 선언을 허용
js
// var
var color = "skyblue";
var color = "yellow"; // 같은 이름으로 다시 선언 가능!
console.log(color); // yellow
// let
let color;
let color; // SyntaxError: 'color' has already been declared
// const
const color = "yellow";
const color = "yellow"; // SyntaxError: 'color' has already been declared
var
는 같은 스코프 안에서 똑같은 이름으로 다시 선언해도 에러가 발생하지 않는다. 마지막에 할당된 값이 적용된다.- 변수명을 중복해서 써도 JavaScript가 막지 않기 때문에, 디버깅을 어렵게 만든다.
let
,const
키워드로 같은 변수를 두 번 선언하면 에러가 발생한다.
2. 변수 호이스팅(끌어올림) 문제
js
console.log(num); // undefined
var num = 10;
js
// 자바스크립트 내부 처리 방식
var num; // 1단계: 변수 선언만 먼저 끌어올림 (undefined로 초기화됨)
console.log(num); // 2단계: 실행, 아직 10은 들어가기 전이니까 undefined
num = 10; // 2단계: 이제야 값이 할당됨
var
는 선언부가 코드의 맨 위로 끌어올려지는 호이스팅이 일어나고, 초기화는 호이스팅되지 않기 때문에undefined
가 출력된다.
js
console.log(color); // ReferenceError: Cannot access 'color' before initialization
let color;
let
이나const
는 호이스팅되더라도TDZ(Temporal Dead Zone)
가 존재해서, 초기화 전 접근 시 오류가 발생한다.
💡 초기화란?
자바스크립트는 실행 전에 변수 선언을 먼저 처리하는데, 이때 변수를 undefined
로 초기화한다. 이 과정을 초기화(initialization)
라고 한다.
var
는 선언과 초기화가 함께 이루어지기 때문에, 선언 전에 접근해도 에러가 발생하지 않는다. 반면, let
과 const
는 초기화가 이루어지기 전까지는 접근할 수 없는 TDZ 상태에 놓이므로, 오류가 발생한다.
왜 undefined 출력이 문제가 될까?
var
가 undefined
를 출력하는 그 자체가 문제는 아니지만, 개발자가 의도하지 않은 동작을 허용한다는 점에서 문제가 된다. 즉, 코드가 틀렸는데도 에러 없이 실행되어 잘못된 결과를 만들 수 있기 때문
이다.
js
// 문제 상황 예시 1
function getUserName() {
console.log(userName); // undefined
var userName = "hyebin";💡
}
getUserName();
- userName을 출력했는데 undefined가 나온다.
- 선언 전에 접근했지만, var는 이를 허용하고 undefined를 출력한다.
- 실수로 순서를 놓쳤는데도 에러가 발생하지 않기 때문에, 문제를 알아차리기 어렵고 디버깅이 힘들어진다.
js
// 문제 상황 예시 2
var total = 100;
function calculate() {
var total = 0; // 개발자는 이 줄을 깜빡할 수도 있다
console.log(total); // 0 ← ??? 왜 total이 100이 아니지?
}
calculate();
- 함수 내부에서 total을 다시 선언했지만, var는 이를 막지 않는다.
- 중복 선언이 실수였더라도, 자바스크립트는 조용히 처리해버린다.
- 오류 메시지는 없지만, 논리적으로 잘못된 결과가 나온다.
진짜 문제는, 에러 없이 잘못된 값이 나온다는 것이다.
- var는 코드에 실수가 있어도 조용히 넘어가며 undefined를 반환하거나 값을 덮어씌운다.
- 그래서 "분명히 맞게 짰는데 결과가 왜 이러지...?" 같은 상황이 자주 생긴다.
js
// let으로 선언 시
console.log(myName); // ReferenceError
let myName = "hyebin";
- let은 초기화 전에 접근 자체를 막기 때문에, 실수를 바로 잡을 수 있다.
- 초기에 에러를 발생시켜 실수를 빠르게 알아차릴 수 있도록 도와주는 것이 큰 장점이다.
3. 함수 스코프만 가진다. (블록 스코프 X)
js
if (true) {
var message = "hello";
}
console.log(message); // "hello"
var
로 선언한 변수는 if, for 같은 블록 내부에 있어도 블록 스코프가 아닌함수 스코프
를 가진다.- 블록 바깥에서도 접근이 가능하기 때문에, 예상과 다른 동작을 유발할 수 있다.
📝 요약
var
는 다음과 같은 이유로 현대 자바스크립트에서 사용을 지양한다.
- 같은 이름의 변수 재선언 허용 → 예기치 않은 덮어쓰기 발생
- 호이스팅 시 초기값이 undefined로 설정 → 실수해도 에러 없이 실행됨
- 블록 스코프를 지원하지 않음 → 코드의 유효 범위가 예상과 달라짐
따라서 현대 JavaScript에서는 let
과 const
를 사용하는 것이 표준이다.
값이 바뀔 수 있는 경우에는 let
, 절대 바뀌지 말아야 하는 값은 const
로 선언하는 것이 권장된다.