JavaScript에서 가장 중요한 문법 중 하나로 변수 선언과 **스코프(Scope)**에 대해 깊이 알아보는 시간을 갖겠습니다. 이 두 가지 개념은 JavaScript에서 코드를 작성할 때 매우 중요한 부분을 차지합니다. 특히, 변수 선언 방식과 스코프의 차이점을 잘 이해해야 의도치 않은 버그를 방지할 수 있습니다. 이번 글에서는 **변수 선언(var, let, const)**과 스코프의 종류, 그리고 **클로저(Closure)**의 개념까지 살펴보고, 각각의 특성을 코드 예제와 함께 자세히 설명하겠습니다.
1. 변수 선언: var, let, const
JavaScript에서 변수를 선언할 때 사용하는 키워드는 var, let, **const**가 있습니다. 이들은 서로 다른 동작 방식을 가지고 있어 적절한 상황에 따라 사용해야 합니다.
1.1 var 키워드
**var**는 JavaScript의 초기부터 사용된 변수 선언 방식으로, **함수 스코프(function scope)**를 따릅니다. 이는 변수가 선언된 함수 내에서만 유효하다는 의미입니다. 하지만 블록 스코프(예: if, for)를 무시하고, 변수가 호이스팅(hoisting)되기 때문에 의도치 않은 동작이 발생할 수 있습니다.
예시:
function exampleVar() {
if (true) {
var x = 10;
}
console.log(x); // 10 (블록 외부에서도 접근 가능)
}
exampleVar();
위 코드에서 var x는 if 블록 안에서 선언되었지만, 함수 전체에서 유효합니다. 이는 var가 블록 스코프를 무시하고, 함수 스코프만 따르기 때문입니다.
또한, var는 호이스팅에 의해 선언이 끌어올려지는 현상이 있습니다.
호이스팅 예시:
console.log(y); // undefined (변수가 선언되었지만 초기화되지 않음)
var y = 5;
위 코드는 var y가 호이스팅되어 변수 선언이 함수 또는 스크립트의 상단으로 끌어올려지지만, 값은 나중에 할당되기 때문에 undefined를 출력합니다.
1.2 let 키워드
**let**은 ES6(ECMAScript 2015)에서 도입된 변수 선언 방식으로, **블록 스코프(block scope)**를 따릅니다. 이는 변수가 선언된 블록 내부에서만 유효하다는 것을 의미합니다. let은 중복 선언이 불가능하고, var보다 더 안전하게 변수를 관리할 수 있습니다.
예시:
function exampleLet() {
if (true) {
let x = 10;
console.log(x); // 10
}
console.log(x); // ReferenceError: x is not defined
}
exampleLet();
위 코드에서 let으로 선언된 변수 x는 if 블록 내부에서만 유효하며, 블록 외부에서 접근하려고 하면 오류가 발생합니다.
또한, let은 호이스팅이 발생하지만, **TDZ(Temporal Dead Zone)**이라는 구역에 들어가게 되어 선언 전에 접근할 수 없습니다.
TDZ 예시:
console.log(z); // ReferenceError: Cannot access 'z' before initialization
let z = 10;
위 코드는 const로 선언된 변수 a에 새로운 값을 할당하려고 할 때 오류를 발생시킵니다. 하지만 객체나 배열의 경우 내부 값을 변경할 수 있습니다.
객체와 배열의 예시:
const obj = { name: 'John' };
obj.name = 'Doe'; // 객체 내부의 속성은 변경 가능
const arr = [1, 2, 3];
arr.push(4); // 배열 내부의 요소 추가 가능
console.log(arr); // [1, 2, 3, 4]
const로 선언된 객체나 배열은 참조 자체를 변경할 수 없지만, 내부의 값은 변경 가능합니다.
2. 스코프(Scope)
스코프란 변수의 유효 범위를 의미하며, 변수가 어디서 접근 가능한지를 결정합니다. JavaScript에서 스코프는 크게 전역 스코프(global scope), 함수 스코프(function scope), **블록 스코프(block scope)**로 나뉩니다.
2.1 전역 스코프(Global Scope)
전역 스코프에서 선언된 변수는 코드 어디에서나 접근할 수 있습니다. 함수 외부에서 선언된 변수가 여기에 해당됩니다.
예시:
let globalVar = 'I am global';
function exampleGlobal() {
console.log(globalVar); // 'I am global'
}
exampleGlobal();
console.log(globalVar); // 'I am global'
위 코드에서 globalVar는 함수 외부에 선언되어 있으므로 전역에서 접근 가능합니다.
2.2 함수 스코프(Function Scope)
**var**로 선언된 변수는 함수 스코프를 따르며, 함수 내부에서만 접근 가능합니다. 함수 내부에 선언된 변수는 외부에서 접근할 수 없습니다.
예시:
function exampleFunctionScope() {
var localVar = 'I am local';
console.log(localVar); // 'I am local'
}
exampleFunctionScope();
console.log(localVar); // ReferenceError: localVar is not defined
위 코드에서 localVar는 함수 내부에서만 유효하므로, 함수 외부에서는 접근할 수 없습니다.
2.3 블록 스코프(Block Scope)
**let**과 **const**로 선언된 변수는 블록 스코프를 따르며, 블록({}) 내부에서만 유효합니다. 조건문, 반복문 등의 블록 내부에서 선언된 변수는 블록 외부에서 접근할 수 없습니다.
예시:
if (true) {
let blockVar = 'I am block scoped';
console.log(blockVar); // 'I am block scoped'
}
console.log(blockVar); // ReferenceError: blockVar is not defined
블록 내부에서 선언된 blockVar는 블록 외부에서 접근할 수 없습니다.
3. 클로저(Closure)
클로저는 함수가 자신이 선언된 환경을 기억하고, 외부 함수의 변수에 접근할 수 있는 개념입니다. 클로저는 JavaScript의 중요한 개념 중 하나로, 주로 캡슐화와 상태 유지에 사용됩니다.
클로저 예시:
function outer() {
let count = 0; // 외부 함수의 변수
return function inner() { // 내부 함수가 외부 변수에 접근
count++;
return count;
};
}
const counter = outer();
console.log(counter()); // 1
console.log(counter()); // 2
console.log(counter()); // 3
위 코드에서 outer 함수는 내부에 count 변수를 가지고 있고, 내부 함수 inner는 이 count 변수에 접근합니다. outer 함수가 종료된 후에도 inner 함수는 count 값을 기억하고, 호출할 때마다 값을 증가시킵니다.
클로저는 상태를 유지하거나 데이터를 은닉하는 데 유용하게 사용됩니다.
'Develop' 카테고리의 다른 글
[jQuery] 드래그 금지, 우클릭 금지, 전체 선택 금지 - 간단 방법 (7) | 2024.10.16 |
---|---|
[Java Javascript] HMAC-SHA256 암호화와 복호화 개념과 예제 (4) | 2024.10.16 |
[JavaScript] 현재 웹페이지의 URL을 가져오는 방법 (5) | 2024.10.12 |
[PostgreSQL] 오브젝트 안에서 로그 찍기 - RAISE 사용해서 출력 (7) | 2024.10.11 |
[PostgreSQL] 날짜 더하기, 빼기, 일수 차이 구하기 INTERVAL (5) | 2024.10.10 |