1️⃣ 변수란?
변수는 데이터를 저장하고 관리하는 이름이 있는 컨테이너입니다. 자바스크립트에서 변수는 프로그램의 동작에 따라 값을 저장, 변경, 삭제하며 다양한 작업을 수행합니다. 변수를 선언할 때는 var, let, const 키워드를 사용합니다.
2️⃣ 변수 선언 키워드 비교
자바스크립트의 변수 선언 방식은 키워드에 따라 작동 방식이 다릅니다. var, let, const는 스코프와 재할당 가능 여부에서 큰 차이가 있으므로, 각각의 특징과 올바른 사용 방법을 이해하는 것이 중요합니다.
1. var
- ES6 이전에 사용되던 변수 선언 방식입니다.
- 함수 스코프를 가지며, 블록 스코프를 지원하지 않습니다.
- 중복 선언이 가능하고, 변수 호이스팅 특성이 있습니다.
2. let
- ES6에서 도입된 변수 선언 방식으로, 블록 스코프를 가집니다.
- 재할당이 가능하며, 중복 선언은 불가능합니다.
3. const
- ES6에서 도입된 상수 선언 방식으로, 블록 스코프를 가집니다.
- 선언과 동시에 초기화가 필요하며, 재할당이 불가능합니다.
- 객체나 배열 같은 참조형 데이터는 내부 값을 변경할 수 있습니다.
3️⃣ 자바스크립트 스코프란?
스코프(Scope)는 변수가 어디까지 유효한지를 결정합니다. 즉, 변수에 접근할 수 있는 범위를 정의합니다.
자바스크립트의 스코프는 크게 전역 스코프, 함수 스코프, 블록 스코프로 나뉩니다.
1. 전역 스코프 (Global Scope)
- 코드 어디서나 접근 가능한 범위입니다.
- 전역 변수는 전역 객체(window 또는 global)에 속하며, 잘못 사용하면 변수 충돌 및 메모리 누수가 발생할 수 있습니다.
var globalVar = "전역 변수";
console.log(globalVar); // 어디서든 접근 가능
2. 함수 스코프 (Function Scope)
- 함수 내부에서만 유효한 범위입니다.
- var 키워드는 함수 스코프를 따릅니다.
function myFunction() {
var localVar = "함수 변수";
console.log(localVar); // 함수 내부에서만 접근 가능
}
// console.log(localVar); // ReferenceError: localVar is not defined
3. 블록 스코프 (Block Scope)
- {}로 감싸진 블록 내에서만 유효한 범위입니다.
- let과 const는 블록 스코프를 따릅니다.
if (true) {
let blockVar = "블록 변수";
console.log(blockVar); // 블록 내부에서만 접근 가능
}
// console.log(blockVar); // ReferenceError: blockVar is not defined
4️⃣ 변수 호이스팅
자바스크립트는 변수를 선언하기 전에 참조할 수 있게 만드는 변수 호이스팅(Variable Hoisting) 동작을 가집니다. 이는 실행 전에 변수 선언이 스코프의 최상단으로 끌어올려지기 때문입니다.
1. var의 호이스팅
var는 선언만 끌어올려지고, 초기화는 끌어올려지지 않으므로 undefined를 반환합니다.
console.log(a); // undefined
var a = 10;
console.log(a); // 10
2. let과 const의 호이스팅
let과 const: 선언만 호이스팅되며, 초기화는 실제 코드 실행 위치에서 이루어집니다. 초기화 전에는 TDZ로 인해 참조가 불가능합니다.
console.log(b); // ReferenceError: Cannot access 'b' before initialization
let b = 10;
동작 과정:
- let b; 선언만 호이스팅되지만 초기화되지 않습니다.
- 초기화(b = 10;)는 실제 코드 실행 시점에서 이루어집니다.
- 초기화 전에는 TDZ로 인해 참조가 불가능합니다.
5️⃣ 스코프 체인 (Scope Chain)
스코프 체인이란?
스코프 체인은 변수를 참조할 때, 변수의 선언 위치를 찾아가는 경로입니다.
변수를 참조할 때 현재 스코프에서 변수를 찾지 못하면, 상위 스코프로 올라가면서 변수를 탐색합니다.
탐색은 현재 스코프 → 부모 스코프 → 전역 스코프 순서로 이루어집니다.
예제와 동작 흐름
let x = "전역 변수"; // 전역 스코프
function outer() {
let x = "함수 변수"; // outer 함수 스코프
function inner() {
console.log(x); // "함수 변수"
}
inner();
}
outer();
동작 과정:
- 전역 스코프:
- 변수 x가 "전역 변수"로 선언됩니다.
- 전역 스코프에서 모든 곳에서 접근할 수 있습니다.
- outer 함수 스코프:
- outer 함수 내부에서 변수 x가 "함수 변수"로 다시 선언됩니다.
- outer 함수 스코프에서 x는 "함수 변수"로 덮어씌워집니다.
- inner 함수 스코프:
- inner 함수 내부에서 x를 참조합니다.
- 현재 스코프(inner)에 x가 없으므로, 스코프 체인을 따라 상위 스코프(outer)에서 x를 찾습니다.
- 결과적으로 "함수 변수"가 출력됩니다.
결과:
함수 변수
6️⃣ 렉시컬 스코프 (Lexical Scope)
렉시컬 스코프란?
자바스크립트는 렉시컬 스코프(Lexical Scope)를 따릅니다.
렉시컬 스코프에서는 변수의 유효 범위가 코드 작성 시점(정적 구조)에 의해 결정됩니다.
즉, 함수가 어디서 호출되었는지가 아니라, 어디서 선언되었는지에 따라 변수를 참조합니다.
예제와 동작 흐름
let x = 10; // 전역 변수
function outer() {
let x = 20; // outer 함수 스코프
function inner() {
console.log(x); // 20
}
inner();
}
outer();
동작 과정:
- 전역 스코프:
- 전역 변수 x는 값 10을 가집니다.
- outer 함수 스코프:
- outer 함수 내부에서 x는 값 20으로 선언됩니다.
- inner 함수 스코프:
- inner 함수 내부에서 x를 참조합니다.
- 렉시컬 스코프에 따라 inner 함수는 자신이 선언된 위치를 기준으로 변수 x를 찾습니다.
- 따라서, inner 함수는 outer 함수 스코프의 x를 참조하여 값 20을 출력합니다.
결과:
20
7️⃣ 클로저와 스코프
클로저란?
클로저(Closure)는 함수가 선언된 렉시컬 스코프를 기억하여, 해당 스코프의 변수에 접근할 수 있는 특성을 의미합니다.
즉, 함수가 선언될 당시의 환경을 기억하며, 이 환경은 함수가 호출된 이후에도 유지됩니다.
클로저의 구조
클로저는 함수와 함수가 선언된 렉시컬 환경으로 구성됩니다.
이 렉시컬 환경에는 변수의 값과 상위 스코프에 대한 참조가 포함됩니다.
클로저 예제
function outer() {
let count = 0; // outer 함수 스코프 변수
return function inner() {
count++; // outer 함수 스코프의 count에 접근
console.log(count);
};
}
const counter = outer(); // outer 실행 -> inner 반환
counter(); // 1
counter(); // 2
동작 과정:
- outer 함수가 실행되면, count라는 변수가 0으로 초기화됩니다.
- outer는 내부 함수 inner를 반환합니다.이때 inner 함수는 outer 함수의 렉시컬 환경(count)을 기억합니다.
- counter()를 호출하면 inner 함수가 실행되고, count++로 count가 증가합니다. 클로저 덕분에 함수가 반환된 이후에도 count 값이 유지됩니다.
결과:
1
2
클로저의 특징
- 클로저는 상위 스코프의 변수에 접근 가능하며, 함수가 반환된 이후에도 상태를 유지합니다.
- 이러한 특성 덕분에 상태 관리, 데이터 은닉, 함수형 프로그래밍 등에서 유용하게 사용됩니다.
8️⃣ 렉시컬 스코프 vs 클로저
특징 렉시컬 스코프 클로저
기본 개념 | 함수의 유효 범위는 작성된 코드 구조로 결정됨 | 함수가 선언된 환경(렉시컬 스코프)을 기억하여 변수에 접근 가능 |
초점 | 함수 선언 시점에서 유효 범위 결정 | 함수 실행 이후에도 선언 당시의 환경 유지 |
활용 사례 | 변수 탐색, 상위 스코프의 변수 참조 | 상태 유지, 데이터 은닉, 비동기 처리 |
8️⃣ var의 단점
1. 변수 호이스팅으로 인한 예기치 않은 동작
console.log(a); // undefined
var a = 10;
2. 블록 스코프 미지원
if (true) {
var x = 10;
}
console.log(x); // 10 (블록 외부에서 접근 가능)
문제점 설명
- var는 블록 스코프를 따르지 않고, 함수 스코프를 따릅니다.
- 따라서, if 블록 내부에서 선언된 변수 x는 블록 외부에서도 유효합니다.
3. 중복 선언 허용
var x = 10;
var x = 20; // 중복 선언 가능
console.log(x); // 20
9️⃣ 결론: let과 const를 사용하세요!!
- 블록 스코프 지원
- let과 const는 블록 내부에서만 유효하므로 의도치 않은 변수 접근을 방지합니다.
- 호이스팅 문제 해결
- 초기화 전에 변수에 접근하면 오류를 발생시켜 코드의 안정성을 높입니다.
- 중복 선언 방지
- let과 const는 동일 스코프에서 중복 선언을 허용하지 않아 유지보수에 유리합니다.
요약 표
특징 var let const
특징 | var | let | const |
스코프 | 함수 스코프 | 블록 스코프 | 블록 스코프 |
호이스팅 | 선언만 호이스팅 | 호이스팅 발생(TDZ 적용) | 호이스팅 발생(TDZ 적용) |
재할당 가능 | 가능 | 가능 | 불가능 (객체 내부 변경 가능) |
중복 선언 | 허용 | 허용하지 않음 | 허용하지 않음 |
'Programming > JavaScript' 카테고리의 다른 글
함수로 알아보는 자바스크립트: 일급 객체와 즉시 호출 함수(IIFE) (1) | 2025.01.07 |
---|---|
자바스크립트 함수 선언과 함수 표현식 (3) | 2025.01.07 |
자바스크립트의 null 병합 연산자 (??) (0) | 2025.01.06 |
자바스크립트의 AND(&&)와 OR(||) 연산 이해하기 (2) | 2025.01.06 |
자바스크립트에서 Falsy 값과 Truthy 값, 그리고 불리언 형 변환 (0) | 2025.01.06 |