Skip to content

변수와 상수

변수 선언 키워드 비교

구분재선언 가능재할당 가능스코프호이스팅TDZ 존재
var가능가능함수 스코프OX
let불가능가능블록 스코프OO
const불가능불가능블록 스코프OO

변수 (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)

  1. 변수명에는 ‘$’와 ‘_’를 제외한 기호는 사용 불가
js
let $name;
let test_data;
  1. 변수명의 맨 앞에는 숫자 사용 불가 (맨 뒤에는 숫자 사용가능)
js
let 9test; // 불가능
let test99; // 가능
  1. 자바스크립트의 예약어 사용 불가
js
let let =  ""; // 에러
let class = "abc" // 에러
  1. 카멜케이스(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 키워드를 사용해 상수를 선언한다.
  • 상수를 선언할 때 반드시 초기값을 함께 할당해야 한다.

상수를 사용하는 이유

  1. 변경되지 않아야 하는 값을 안전하게 저장하기 위해 사용 (변경 방지)
js
const birth = "04-07";
const name = "hyebin";
  1. 기억하기 쉽게 만들기 위해
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는 선언과 초기화가 함께 이루어지기 때문에, 선언 전에 접근해도 에러가 발생하지 않는다. 반면, letconst는 초기화가 이루어지기 전까지는 접근할 수 없는 TDZ 상태에 놓이므로, 오류가 발생한다.

왜 undefined 출력이 문제가 될까?

varundefined를 출력하는 그 자체가 문제는 아니지만, 개발자가 의도하지 않은 동작을 허용한다는 점에서 문제가 된다. 즉, 코드가 틀렸는데도 에러 없이 실행되어 잘못된 결과를 만들 수 있기 때문이다.


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에서는 letconst를 사용하는 것이 표준이다.
값이 바뀔 수 있는 경우에는 let, 절대 바뀌지 말아야 하는 값은 const로 선언하는 것이 권장된다.