JavaScript의 스코프(Scope)

JavaScript의 스코프(Scope)는 변수가 접근할 수 있는 범위를 결정하는 중요한 개념입니다. 스코프는 코드의 구조를 이해하고 디버깅하는 데 도움을 주며, 변수와 함수의 유효 범위를 이해하는 데 필수적입니다. 이번 글에서는 변수 스코프와 호이스팅에 대해 자세히 설명하겠습니다.

변수 스코프

전역 스코프(Global Scope)

전역 스코프는 코드 어디에서나 접근할 수 있는 범위를 의미합니다. 전역 스코프에 선언된 변수는 전역 객체(window 또는 global)의 속성이 됩니다.

var globalVar = "I am global";

function displayGlobalVar() {
  console.log(globalVar); // "I am global"
}

displayGlobalVar();
console.log(globalVar); // "I am global"

위 예제에서 globalVar는 전역 변수로, 함수 내외부에서 모두 접근할 수 있습니다.

함수 스코프(Function Scope)

함수 스코프는 함수 내부에서만 접근할 수 있는 범위를 의미합니다. 함수 내부에서 선언된 변수는 함수 외부에서 접근할 수 없습니다.

function functionScopeExample() {
  var localVar = "I am local";
  console.log(localVar); // "I am local"
}

functionScopeExample();
// console.log(localVar); // ReferenceError: localVar is not defined

위 예제에서 localVar는 함수 내부에서만 유효하며, 함수 외부에서는 접근할 수 없습니다.

블록 스코프(Block Scope)

블록 스코프는 블록({}) 내부에서만 접근할 수 있는 범위를 의미합니다. letconst 키워드는 블록 스코프를 가지며, 블록 외부에서는 접근할 수 없습니다.

if (true) {
  let blockScopedVar = "I am block scoped";
  console.log(blockScopedVar); // "I am block scoped"
}
// console.log(blockScopedVar); // ReferenceError: blockScopedVar is not defined

위 예제에서 blockScopedVar는 블록 내부에서만 유효하며, 블록 외부에서는 접근할 수 없습니다.

호이스팅(Hoisting)

호이스팅은 변수와 함수 선언이 해당 스코프의 최상단으로 끌어올려지는(JavaScript 인터프리터에 의해) 동작을 의미합니다. 호이스팅은 코드의 실행 순서에 영향을 미치지 않지만, 변수와 함수의 접근 가능 시점에 영향을 줍니다.

변수 호이스팅

변수 선언은 호이스팅되지만, 변수의 초기화는 호이스팅되지 않습니다. 따라서 초기화 전에 변수를 참조하면 undefined가 반환됩니다.

console.log(hoistedVar); // undefined
var hoistedVar = "I am hoisted";
console.log(hoistedVar); // "I am hoisted"

위 예제에서 hoistedVar는 선언이 호이스팅되지만, 초기화는 호이스팅되지 않습니다. 따라서 첫 번째 console.logundefined를 출력합니다.

letconst로 선언된 변수는 호이스팅되지만, 선언 전에 접근하면 ReferenceError가 발생합니다.

// console.log(hoistedLet); // ReferenceError: Cannot access 'hoistedLet' before initialization
let hoistedLet = "I am hoisted with let";

console.log(hoistedLet); // "I am hoisted with let"

함수 호이스팅

함수 선언은 변수 선언과 달리 전체가 호이스팅됩니다. 따라서 함수 선언문은 선언 전에 호출할 수 있습니다.

hoistedFunction(); // "I am hoisted"

function hoistedFunction() {
  console.log("I am hoisted");
}

위 예제에서 hoistedFunction은 선언과 정의가 모두 호이스팅되므로, 선언 전에 호출할 수 있습니다.

반면 함수 표현식은 변수 선언과 유사하게 호이스팅됩니다. 따라서 함수 표현식으로 정의된 함수는 선언 전에 호출할 수 없습니다.

// hoistedExpression(); // TypeError: hoistedExpression is not a function

var hoistedExpression = function() {
  console.log("I am not hoisted");
};

hoistedExpression(); // "I am not hoisted"

위 예제에서 hoistedExpression은 변수 선언이 호이스팅되지만, 함수 정의는 호이스팅되지 않으므로 선언 전에 호출할 수 없습니다.

스코프 체인(Scope Chain)

스코프 체인은 중첩된 함수나 블록의 스코프에서 변수를 찾는 과정입니다. 현재 스코프에서 변수를 찾지 못하면, 상위 스코프에서 변수를 찾습니다. 이 과정은 전역 스코프에 도달할 때까지 계속됩니다.

var globalVar = "I am global";

function outerFunction() {
  var outerVar = "I am outer";

  function innerFunction() {
    var innerVar = "I am inner";
    console.log(globalVar); // "I am global"
    console.log(outerVar); // "I am outer"
    console.log(innerVar); // "I am inner"
  }

  innerFunction();
}

outerFunction();

위 예제에서 innerFunctionglobalVar, outerVar, innerVar를 모두 참조할 수 있습니다. 이는 스코프 체인을 통해 변수를 찾기 때문입니다.

결론

JavaScript의 스코프와 호이스팅은 변수와 함수의 유효 범위와 접근 가능 시점을 결정하는 중요한 개념입니다. 전역 스코프, 함수 스코프, 블록 스코프를 이해하고, 호이스팅이 코드 실행에 미치는 영향을 이해하면, 더 안정적이고 예측 가능한 코드를 작성할 수 있습니다. 스코프 체인을 잘 활용하면 코드의 가독성과 유지보수성을 높일 수 있습니다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다