[Javascript] 함수의 스코프(Scope)

박세화·2024년 1월 4일
0

Javascript

목록 보기
5/12

스코프 체인(scope chaning)

자바스크립트에서 함수는 변수에 접근할 때 상위 함수로 연속해서 접근하며 값을 찾는다.
즉 변수를 참조할 때 하위 스코프에서 상위 스코프로 무조건 위로만 올라간다! 따라서 내부 함수에서 외부 함수를 참조할 수 있지만 반대는 불가능하다.

const x = "global x";

function outer() {
  const y = "local y of outer func";
  console.log(x);  //global x
  console.log(y);  //local y of outer func

  function inner() {
    const x = "local x of inner func";
    console.log(x);  //local x of inner func
    console.log(y);  //local y of outer func
  }
  inner();
}

outer();
console.log(x);  //global x
console.log(y);  //Reference Error

inner 함수 내에서console.log(y)를 실행하려 할 때, 자신의 지역 스코프에서 먼저 값을 찾으려 하겠지만 변수 y에 해당하는 값이 없다.
그렇다면 자신의 바로 바깥 스코프인 outer의 지역 스코프 내에서 변수 y에 대한 값을 탐색한다.
여기서 const y = "local y of outer func"를 찾았기에, 콘솔에 local y of outer func이 찍히는 것이다.

그렇다면 이 코드에서 inner 함수 내부 변수 x 선언 라인이 없어지면 어떻게 바뀔까?

const x = "global x";

function outer() {
  const y = "local y of outer func";
  console.log(x);  //global x
  console.log(y);  //local y of outer func

  function inner() {
    console.log(x);  //global x
    console.log(y);  //local y of outer func
  }
  inner();
}

outer();
console.log(x);  //global x
console.log(y);  //Reference Error

inner 함수 내의 console.log(x)를 보자.
변수 x가 inner 지역 스코프에 없다. 그렇다면 위로 올라가 outer의 지역 스코프에서 값을 찾아본다. 여기에도 없다!
그렇다면 한 번 더 위로 올라가 이젠 전역 스코프(window)로 나간다. 여기서 const x = "global x" 라는 라인을 찾는다.
그 결과, 콘솔에 global x이 찍히는 것이다.

정적 스코프(lexical scoping)

자바스크립트의 스코프는 함수를 호출할 때가 아니라 선언할 때 생긴다. 그렇기 때문에 한 스코프의 상위 스코프 또한 함수가 정의되는 시점에 결정된다.

let cat = "zero";

function log() {
  console.log(cat);
}

function wrapper() {
  cat = "nero";
  log();
}

wrapper();  //nero

여기에서 결과는 nero 이다.

let cat = "zero";

function log() {
  console.log(cat);
}

function wrapper() {
  let cat = "nero";
  log();
}

wrapper();  //zero

하지만 위 예시에서 결과는 zero이다.
log 함수 안의 cat자신이 선언되는 시점의 바깥let cat = "zero"을 참조하기 때문이다.

첫 번째 예시를 다시 보면, 마찬가지로 이 경우도 log 함수는 자신의 바깥인 let cat = "zero"을 참조한다. 하지만 콘솔이 찍히기 전 wrapper함수 내에서 catnero로 재선언되었을 뿐이다.

💡 스코프 레벨의 종류
프로그래밍 언어에서 스코프 레벨은 크게 블록 레벨 스코프함수 레벨 스코프로 나뉜다.
블록 레벨 스코프에서는 if문, for문 그리고 함수 단위로 스코프를 나눌 수 있으며, 대부분의 프로그래밍 언어가 이에 속한다. 반면 함수 레벨 스코프에서는 이름에서도 알 수 있듯이 함수 단위로만 스코프가 쪼개진다. 자바스크립트는 함수 레벨 스코프 특성만을 가지고 있었지만, ES6에서 let과 const가 도입되면서 블록 레벨 스코프의 특성 또한 가질 수 있게 되었다.

0개의 댓글