자바스크립트로 개발하는 데 있어서 필요한 필수 개념들을 정리할 예정입니다. 우선은 스코프 (scope)와 var / let / const에 대해서 정리해보았습니다.
스코프 (scope)란?
스코프는 변수나 함수가 유효한 범위를 나타내는 개념입니다.
스코프는 코드 내에서 변수에 접근할 수 있는 범위를 결정하며, 변수의 유효성과 생존 기간을 관리합니다.
스코프는 변수가 어디서 유효한지를 결정하므로, 변수의 충돌을 방지하고 코드의 안정성을 높이는 데 중요한 역할을 합니다.
함수나 블록 내에서 선언된 변수는 외부에서 직접 접근할 수 없으며, 이는 변수의 의도치 않은 수정을 방지합니다.
스코프는 전역 스코프, 지역 스코프, 블록 스코프로 구분할 수 있습니다.
전역 스코프 (Global Scope)
전역 스코프는 코드의 가장 바깥 영역으로, 어디서든 접근할 수 있는 공간입니다.
전역 스코프에서 선언된 변수는 프로그램 전체에서 사용 가능합니다.
var globalVar = "I'm global!";
function exampleFunction() {
console.log(globalVar); // 전역 변수에 접근 가능
}
지역 스코프 (Local Scope 또는 Function Scope)
지역 스코프는 함수 내에서 선언된 변수가 유효한 범위입니다.
함수가 호출될 때마다 해당 함수 내에서만 접근 가능한 새로운 스코프가 생성됩니다.
function exampleFunction() {
var localVar = "I'm local!";
console.log(localVar); // 지역 변수에 접근 가능
}
블록 스코프 (Block Scope)
ES6 (ECMAScript 2015)에서 let과 const 키워드로 도입된 블록 스코프는 중괄호 {} 내에서 변수가 유효한 범위를 제한합니다.
var로 선언된 변수는 로컬 스코프이지만, let과 const로 선언된 변수는 블록 스코프를 갖습니다.
if (true) {
let blockVar = "I'm in a block!";
console.log(blockVar); // 블록 변수에 접근 가능
}
함수 스코프와 블록 스코프의 차이
이름에서 두 스코프의 차이를 이미 설명해주고 있습니다.
함수 스코프는 함수에서만 유효한 범위를 가지며, 블록 스코프는 함수와 중괄호 {} 내에서만 유효한 범위를 가집니다.
function exampleFunction() {
var localVar = "I'm local!";
console.log(localVar); // 함수 내에서 유효한 로컬 변수
}
exampleFunction() // I'm local!
// console.log(localVar); // 에러: localVar는 함수 외부에서는 유효하지 않음
if (true) {
let blockVar = "I'm in a block!";
console.log(blockVar); // 블록 내에서 유효한 블록 변수
}
// console.log(blockVar); // 에러: blockVar는 블록 외부에서는 유효하지 않음
let은 블록 스코프라서 블록 외부에서 사용하면 ReferenceError가 발생하지만 var 키워드는 함수 스코프이기 때문에 함수 내부가 아닌 블록 내부에서 사용한 변수를 블록 외부에서도 사용 가능합니다.
if (true) {
var funcVar = "I'm in a block! but have function scope!!!";
// 블록 내/외에서 유효
console.log(funcVar); //output: I'm in a block! but have function scope!!!
}
// 블록 내/외에서 유효
console.log(funcVar); //output: I'm in a block! but have function scope!!!
let과 var의 차이는 바로 다음 문단에서 const 키워드와 함께 설명 드리겠습니다.
키워드 var / let / const
var, let, const는 모두 변수를 선언하는 데 사용되는 키워드로, 각각의 특징과 차이점이 있습니다.
var
var는 함수 레벨 스코프를 따릅니다.
하지만 블록 레벨 스코프를 따르지는 않습니다. (반복문, 조건문 등)
*호이스팅(Hoisting)이 발생합니다. 변수 선언이 해당 스코프의 맨 위로 끌어올려져 실행됩니다.
호이스팅 이란?
호이스팅(Hoisting)은 JavaScript에서 변수 및 함수 선언이 스코프의 최상단으로 끌어올려지는 현상을 나타냅니다. 즉, 코드 내에서 변수나 함수를 선언하기 전에도 참조할 수 있는 것처럼 동작합니다.
호이스팅은 선언부만 끌어올려지며, 초기화는 끌어올려지지 않습니다. 변수는 undefined로 초기화되고, 함수는 정의된 내용이 그대로 유지됩니다.
아래의 코드에서 var x = 5;와 function hoistedFunction()이 선언되기 전에도 참조할 수 있습니다. 그러나 변수 x는 선언 시점에는 undefined로 초기화되어 있습니다.
console.log(x); // undefined
var x = 5;
hoistedFunction(); // "I'm hoisted!"
function hoistedFunction() {
console.log("I'm hoisted!");
}
아래 같이 중복 선언 및 재할당이 가능합니다.
var i = 100;
var i = 200; // 중복 선언
console.log(i) // 200
i = 300; // 재할당
console.log(i) //300
전역 스코프에서 변수를 선언했어도, 함수 내에서 선언한다면 중복 선언이 아니라 함수 스코프 내에서 새롭게 선언한 변수가 됩니다.
var funcScope = 100;
function exampleFunction(){
var funcScope = 200;
console.log(funcScope)
}
exampleFunction() // 200
console.log(funcScope) //100
var 키워드는 블록 레벨 스코프를 따르지 않다는 점. 그리고 중복 선언이 가능한 점 때문에 코드 작성에서 혼돈이 생길 수 있습니다.
때문에 var 변수는 가급적이면 사용하지 않습니다…!
var 키워드를 사용하면 아래와 같은 예에서 문제 생길 수 있습니다.
var i = 100;
// 의도치 않은 중복 선언
for(var i=1; i<5; i++){
console.log(i)
}
console.log(i) // 5
위의 코드에서 변수 i는 100에서 1로 의도치 않게 재선언 되었습니다. 때문에 마지막의 줄의 i는 100이 아닌 5가 출력이 됩니다.
let
let은 함수 레벨 스코프와 블록 레벨 스코프를 모두 따릅니다.
let은 중복 선언은 안되지만 재할당은 됩니다.
let i = 100;
// let i = 200; // SyntaxError : 중복 선언 불가
console.log(i) // 100
i = 300; // 재할당
console.log(i) // 300
let은 중복 선언이 안되고 블록 스코프를 가지기 때문에 아래 예와 같이 의도치 않은 중복 선언을 방지할 수 있습니다.
let i = 100;
console.log(i) // 100
// 반복문의 i는 중복 선언이 아닌 블록 스코프에서 새롭게 선언된 i
// var와 달리 의도치 않은 중복 선언 방지됨
for(let i=1; i<5; i++){
console.log(i)
}
console.log(i) //100
let 키워드를 다른 스코프에서 사용할 때 전역 스코프의 변수를 재할당하려는 것인지 블록 스코프에서 새롭게 변수를 선언하려는 것인지 구분해서 사용해야 합니다.
let i = 100;
if (true) {
let i = 200; // 블록 스코프 내에서의 새로운 변수 선언
console.log("블록 내부:", i); // 200
}
console.log("전역:", i); // 100
if (true) {
i = 200; // 전역 변수 i를 재할당
console.log("블록 내부:", i); // 200
}
console.log("전역:", i); // 200
const
const는 상수를 선언하는 데 사용됩니다.
중복 선언이 불가능 합니다.
const constVar = "3.1415";
//const constVar = "3.141592"; //SyntaxError
재할당이 불가능 합니다.
const constVar = "3.1415";
//constVar = "3.141592"; //SyntaxError
그러나 객체나 배열과 같은 참조형 데이터의 내부 값은 변경할 수 있습니다.
const constVar = [1,2,3,4];
constVar.push(5)
console.log(constVar) //[ 1, 2, 3, 4, 5 ]
블록 스코프를 가지고 있습니다.
if (true){
const constVar = "I am a const"
console.log(constVar) //I am a const
}
//console.log(constVar) //ReferenceError
let, var 키워드와 달리 const는 선언과 동시에 초기화해야 합니다.
let letVar;
var varVar;
//const constVar; //SyntaxError
Hangbok Archive