[JavaScript] 스코프(Scope)

정진우·2024년 5월 15일
0

JavaScript

목록 보기
10/20
post-thumbnail

스코프란?

  • 스코프(Scope)는 변수와 함수의 접근성을 나타내는 개념입니다. 스코프는 변수나 함수가 어디에서 접근 가능한지를 결정하며, 스코프 체인(Scope Chain)이라고도 불립니다. 자바스크립트는 스코프를 기반으로 변수를 검색하고 식별합니다. 전역 스코프(Global Scope)지역 스코프(Local Scope) 로 구분됩니다.
  • 스코프는 변수를 검색하는 메커니즘을 정의합니다. 변수가 사용되면 자바스크립트 엔진은 현재 스코프에서 시작하여 변수를 찾습니다. 만약 변수가 현재 스코프에 없다면, 상위 스코프로 이동하여 다시 검색합니다. 이런 식으로 스코프 체인을 따라 올라가며 변수를 찾습니다.
  • 함수 내에서 선언된 변수는 해당 함수의 지역 스코프에 속하므로 외부에서 접근할 수 없습니다. 하지만 함수는 자신이 정의된 스코프 외부에서도 호출될 수 있으므로, 함수 내부에서 외부 스코프의 변수에 접근할 수 있습니다. 이러한 기능을 클로저(Closure)라고 합니다. 클로저는 나중에 정리 해보겠습니다.

스코프의 구분

  • 전역 스코프(Global Scope) : 프로그램 전체에서 유효한 스코프입니다. 전역 스코프에서 선언된 변수와 함수는 프로그램 어디에서든 접근할 수 있습니다.
  • 지역 스코프(Local Scope) : 특정한 블록이나 함수 내에서 유효한 스코프입니다. 지역 스코프에서 선언된 변수와 함수는 해당 블록이나 함수 내에서만 접근할 수 있습니다.
  • 전역 변수(Global variable) : 전역 스코프에서 선언된 변수를 말합니다. 프로그램 어디에서든 접근할 수 있으며, 전역 변수의 값은 프로그램 전체에서 유지됩니다.
  • 지역 변수(Local variable) : 지역 스코프 내에서 선언된 변수를 말합니다. 해당 변수는 선언된 블록이나 함수 내에서만 유효하며, 외부에서 접근할 수 없습니다. 지역 변수는 해당 블록이나 함수가 실행되는 동안에만 존재하고 유지됩니다.

전역 스코프(Global Scope)

전역 스코프에 선언된 변수와 함수는 어디서든 접근 가능합니다. 이는 스크립트 전체에서 유효한 스코프입니다.

  • 전역 스코프에 선언된 변수와 함수는 어디서든지 접근할 수 있습니다. 즉, 전역 스코프에 선언된 변수는 코드의 어느 곳에서나 사용할 수 있으며, 전역 스코프에 선언된 함수도 어디서든 호출할 수 있습니다.
// 전역 스코프에 변수와 함수를 선언합니다.
let globalVariable = "I am a global variable";

function globalFunction() {
  console.log("I am a global function");
}

// 전역 스코프에 선언된 변수와 함수는 어디서든 접근할 수 있습니다.
console.log(globalVariable); // "I am a global variable"
globalFunction(); // "I am a global function"

// 함수 내부에서도 전역 변수와 함수에 접근할 수 있습니다.
function anotherFunction() {
  console.log(globalVariable); // "I am a global variable"
  globalFunction(); // "I am a global function"
}

anotherFunction();
  • globalVariableglobalFunction()은 전역 스코프에서 선언되었기 때문에 어디서든 접근할 수 있습니다. anotherFunction()내에서도 전역 변수와 함수에 접근할 수 있습니다.

스크립트의 가장 바깥쪽에서 선언된 변수와 함수는 전역 스코프에 속합니다.

  • "스크립트의 가장 바깥쪽에서 선언된" => 코드의 최상단에 선언되었다는 의미입니다. 스크립트의 시작 부분에 해당합니다. 따라서 코드의 바깥쪽에서 선언된 변수와 함수는 전역 스코프에 속하게 됩니다.
// 이 부분이 코드의 최상단입니다.
let globalVariable = 10;

function globalFunction() {
  console.log("This is a global function");
}

console.log(globalVariable); // 10
globalFunction(); // This is a global function
  • globalFunction()함수가 다른 함수보다 상위에 위치해 있다면, 이 함수는 전역 스코프에 속하게 됩니다. 따라서 globalFunction()함수는 코드의 최상단에 선언된 함수 입니다.
  • 변수와 함수는 각각 독립적으로 정의됩니다. 코드 내에서 변수와 함수의 선언 위치가 서로에게 영향을 주지 않습니다. 변수와 함수는 각각 자신만의 스코프를 가지며, 이는 선언된 위치에 따라 결정됩니다. 변수가 최상단에 선언되어도 함수의 위치에 영향을 주지 않고, 함수가 최상단에 선언되어도 변수의 위치에 영향을 주지 않습니다.

지역 스코프(Local Scope)

함수 내에서 선언된 변수와 함수는 해당 함수 내부에서만 접근할 수 있습니다.

function exampleFunction() {
  var localVariable = "Local"; // 지역 변수
  console.log(localVariable); // "Local"
}

exampleFunction(); // Local
console.log(localVariable); // ReferenceError: localVariable is not defined
  • LocalVariableexampleFunction() 함수 내에서 선언된 지역 변수 입니다. 이 변수는 exampleFunction() 함수 내에서만 유효하며, 함수 외부에서는 접근할 수 없습니다. 함수 외부에서 LocalVariable을 참조하려고 하면 ReferenceError가 발생합니다.

블록 스코프(Block Scope)

  • 블록 스코프는 중괄호({})로 둘러싸인 코드 블록 내에서 변수가 유효한 스코프를 의미합니다.
  • 블록 스코프는 ES6(2015)에서 letconst 키워드를 사용하여 도입되었습니다.
  • if, for, while 등과 같은 제어문 또는 함수 내에서 중괄호로 둘러싸인 영역이 블록 스코프 입니다.
if (true) {
    let blockVariable = "I'm a block scoped variable";
    console.log(blockVariable); // 출력: "I'm a block scoped variable"
}
console.log(blockVariable); // ReferenceError: blockVariable is not defined
  • if문 내에서 선언된 변수는 해당 if 문 블록 내에서만 유효하며, 외부에서는 접근할 수 없습니다.

함수 스코프(Function Scope)

  • 함수 스코프란 변수가 선언된 함수의 범위 내에서만 접근 가능하다는 것을 의미합니다.
  • 함수 내에서 선언된 변수는 해당 함수 내에서만 유효하며, 함수 외부에서는 접근할 수 없습니다.
  • 이전에는 JS에서 함수 스코프가 유일한 스코프 방식이였습니다. var 키워드로 선언된 변수는 함수 스코프를 가집니다.
  • var로 선언된 변수는 선언된 함수의 전체 범위, 즉 함수 내부에서는 어디에서나 사용할 수 있습니다. 즉, 함수 내부의 어떤 위치에서든 해당 변수를 참조하거나 값을 변경하는 것이 가능합니다.

예제 1

function loop() {
  for (var i = 0; i < 7; i++) {
    console.log(i);
  }
  console.log(i, "번호끝!");
}
loop();
/*
  0
  1
  2
  3
  4
  5
  6
  7 번호끝!
*/
  • 이 코드는 for문 내에서 var 키워드를 사용하여 i 변수를 선언했습니다.
  • 그래서 for 문 밖에서도 i에 접근할 수 있습니다.
  • var 키워드를 사용하여 i 변수를 선언하였기 때문에, for 반복문이 끝난 후에도 i 변수에 접근할 수 있습니다. 이 때문에 console.log(${i} 번호끝!) 코드는 7 번호끝!을 콘솔에 출력합니다. 이는 for 반복문의 조건 i < 7 때문에 i 값이 7이 되면 반복문이 종료되지만, i 값 자체는 변하지 않기 때문입니다.
  • var는 함수 스코프를 가지기 때문에 함수 내부에서는 어디에서나 사용할 수 있습니다.

예제 2

function loop() {
  for (let i = 0; i < 7; i++) {
    console.log(i);
  }
  console.log(i, "번호끝!");
}
loop();
/*
  0
  1
  2
  3
  4
  5
  6

  ReferenceError: i is not defined
*/
  • for문 내에서 let 키워드를 사용하여 i 변수를 선언했습니다.
  • i < 7이라는 조건식 때문에 i의 값이 7이 되는 순간 for문은 종료되고, 그 때문에 i의 값 7은 출력되지 않습니다. for문 내의 console.log(i)i가 0부터 6까지의 값일 때만 실행되기 때문입니다. 그래서 결과적으로 콘솔에는 0부터 6까지의 숫자만 출력됩니다.
  • letconst는 블록 스코프의 특성을 가집니다. 그래서 for문 내에서 ilet로 선언한 순간, 변수 i는 for문 내에서만 접근이 가능하기 때문에 for문 외부에서는 i에 접근할 수 없습니다.
변수재할당재선언유효범위
let가능불가블록 스코프 및 함수 스코프
const불가불가블록 스코프 및 함수 스코프
var가능불가함수스코프

스코프 체인

스코프 체인(scope chain)은 자바스크립트에서 변수의 접근을 결정하는 메커니즘입니다. 이 메커니즘은 함수와 블록 내에서 변수를 어떻게 검색하고 접근할지를 정의합니다. 스코프 체인은 내부 함수나 블록에서 변수를 찾지 못했을 때 외부 스코프에서 변수를 검색하는 과정을 설명합니다.

스코프 체인의 동작 원리

스코프 체인은 내부 스코프에서 변수를 찾지 못하면 외부 스코프로 이동하여 변수를 검색합니다. 이는 전역 스코프에 도달할 때까지 계속 됩니다.

예제 - 블록 스코프와 함수 스코프

function test() {
  if (true) {
    const blockScoped = "I am block scoped";
    var functionScoped = "I am function scoped";
  }

  console.log(functionScoped); // 출력: I am function scoped
  console.log(blockScoped); // ReferenceError: blockScoped is not defined
}

test();
  • const로 선언된 blockScoped 변수는 블록 스코프이며, 블록을 벗어나면 접근할 수 없습니다.
  • var로 선언된 functionScoped 변수는 함수 스코프이며, 함수 내 어디서든 접근할 수 있습니다.

예제 - 스코프 체인

const animal = "Lion";

function outerFunction() {
  const animal = "Elephant";

  function innerFunction() {
    console.log(animal);
  }

  innerFunction();
}

outerFunction(); // 출력: Elephant
  • innerFunctionouterFunction내부에 정의된 함수입니다.
  • innerFunction에서 animal 변수를 검색할 때, 먼저 innerFunction의 스코프에서 찾습니다. 해당 스코프에서 변수를 찾지 못할경우 outerFunction의 스코프로 이동하여 변수를 찾습니다. 여기서 animal 변수를 발견하고 "Elephant"를 출력합니다.

스코프 체인의 단계별 동작

  1. 변수 선언
    • 변수는 특정 스코프 내에서 선언됩니다. (전역, 함수, 블록)
  2. 변수 검색
    • 변수를 사용할 때, 자바스크립트 엔진은 해당 스코프 내에서 변수를 검색합니다.
    • 변수를 찾지 못하면 외부 스코프로 이동하여 검색을 계속합니다.
    • 이 과정은 전역 스코프에 도달할 때까지 반복됩니다.
  3. 변수 접근
    • 변수를 찾으면 해당 값을 사용합니다.
    • 변수를 끝까지 찾지 못하면 ReferenceError가 발생합니다.

변수의 생명 주기(Lifecycle)

변수의 생명 주기는 변수가 메모리에 존재하는 기간을 의미합니다. 변수의 생명 주기는 변수의 선언 위치와 스코프에 따라 달라집니다.

전역 변수의 생명 주기

  • 전역 변수는 애플리케이션이 실행될 때 생성되고, 종료될 때까지 메모리에 존재합니다.
var globalVar = "I am a global variable";
// 애플리케이션 시작 시 globalVar가 메모리에 할당됩니다.

함수 스코프 변수의 생명 주기

  • 함수 스코프 변수는 함수가 호출될 때 생성되고, 함수 실행이 종료되면 메모리에서 소멸됩니다.
function myFunction() {
  var functionScopedVar = "I am function scoped";
  console.log(functionScopedVar);
}

myFunction(); // 함수가 호출될 때 functionScopedVar가 생성됩니다.
// 함수가 종료되면 functionScopedVar는 메모리에서 소멸됩니다.

블록 스코프 변수의 생명 주기

  • 블록 스코프 변수는 블록이 실행될 때 생성하고, 블록 실행이 종료되면 메모리에서 소멸됩니다.
{
  let blockScopedVar = "I am block scoped";
  console.log(blockScopedVar); // 접근 가능
}
// 블록이 종료되면 blockScopedVar는 메모리에서 소멸됩니다.

참고

profile
내가 바뀌지 않으면 아무것도 바뀌지 않는다 🔥🔥🔥

0개의 댓글