13. 스코프

2022. 10. 24. 15:16기록/Modern JavaScript Deep Dive

    목차

스코프란?

  • 식별자가 유효한 범위
  • 식별자가 선언된 위치에 의해서 유효 범위가 결정됨
  • 식별자 결정 : 이름이 같은 변수 중에서 어떤 변수를 참조할 지 결정하는 것
  • 변수 이름의 충돌을 방지함

스코프의 종류

1. 전역과 전역 스코프

  • 전역 : 코드의 가장 바깥 영역
  • 전역은 전역 스코프를 만듦
  • 전역에 변수를 선언하면 전역 변수가 됨
  • 전역 변수는 어디서든지 참조 가능

2. 지역과 지역 스코프

  • 지역 : 함수 몸체 내부
  • 지역은 지역 스코프를 만듦
  • 지역에 변수를 선언하면 지역 변수가 됨
  • 지역 변수는 자신의 지역 스코프와 하위 지역 스코프에서 유효함

스코프 체인

  • 스코프가 계층적으로 연결된 것
  • 스코프는 함수의 중첩에 의해 계층적 구조를 가짐
  • 외부 함수의 지역 스코프 === 중첩 함수의 상위 스코프
  • 모든 지역 스코프의 최상위 스코프는 전역 스코프임

 

자바스크립트 엔진은 스코프 체인을 통해 변수를 참조하는 코드의 스코프에서 시작해서

상위 스코프 방향으로 이동하면서 선언된 변수를 검색한다.

  • 하위 스코프 → 상위 스코프 // 참조 가능
  • 상위 스코프 → 하위 스코프 // 참조 불가능

 

1. 스코프 체인에 의한 변수 검색

var x = "global x";
var y = "global y";

function outer() {
  var z = "outer's local z";

  function inner() {
    var x = "inner's local x";
    
    console.log(x); // 1번
    console.log(y); // 2번
    console.log(z); // 3번
  }
  
  inner();
}

outer();

1번 코드가 실행될 때 변수 검색 

  • x변수를 참조하는 코드의 스코프인 inner 함수의 지역 스코프에서 x변수가 선언되었는지 검색함
  • inner 함수 내에는 선언된 x 변수가 존재함
  • 검색된 변수를 참조하고 검색을 종료함

 

2번 코드가 실행될 때 변수 검색

  • y변수를 참조하는 코드의 스코프인 inner 함수의 지역 스코프에서 y변수가 선언되었는지 검색함
  • inner 함수 내에는 y변수의 선언이 존재하지 않음
  • 상위 스코프인 outer 함수의 지역 스코프로 이동함
  • outer 함수 내에도 y변수의 선언이 존재하지 않음
  • 상위 스코프인 전역 스코프로 이동함
  • 전역 스코프에는 y변수의 선언이 존재함
  • 검색된 변수를 참조하고 검색을 종료함

 

3번 코드가 실행될 때 변수 검색

  • z변수를 참조하는 코드의 스코프인 inner 함수의 지역 스코프에서 z변수가 선언되었는지 검색함
  • inner 함수 내에는 z변수의 선언이 존재하지 않음
  • 상위 스코프인 outer 함수의 지역 스코프로 이동함
  • outer 함수 내에는 z변수의 선언이 존재함
  • 검색된 변수를 참조하고 검색을 종료함

 

2. 스코프 체인에 의한 함수 검색

  • 함수도 식별자이기 때문에 스코프를 가짐
  • 스코프는 "변수를 검색하는 규칙" 이 아니라 "식별자를 검색하는 규칙"

함수 레벨 스코프

  • 블록 레벨 스코프 : 모든 코드 블록이 지역 스코프를 생성함 (let, const)
  • 함수 레벨 스코프 : 함수의 코드 블록만 지역 스코프를 생성함 (var)

 

var x = 1;

if (true) {
  var x = 10;
}

console.log(x); // 10
  • var 키워드로 선언된 변수는 함수의 코드 블록만 지역 스코프로 인정함
  • 함수 밖에서 var 키워드로 선언된 변수는 모두 전역 변수임
  • 이미 선언된 전역 변수 x가 있기 때문에 x변수는 중복 선언됨
  • 의도치 않게 변수 값이 변경되는 부작용이 발생함

렉시컬 스코프

var x = 1;

function foo() {
  var x = 10;
  bar();
}

// bar 함수의 상위 스코프는 자신이 정의된 스코프 === 전역 스코프
function bar() {
  // 전역 스코프에 선언된 변수x 출력
  console.log(x);
}

foo(); // 1
bar(); // 1

렉시컬 스코프 (정적 스코프)

  • 함수 정의가 평가될 때 상위 스코프가 결정됨
  • 함수가 호출된 위치는 상위 스코프 결정에 영향을 주지 않음
  • 함수의 상위 스코프는 항상 자신이 정의된 스코프임
  • 함수 정의가 실행되어 생성된 함수 객체는 결정된 상위 스코프를 기억함
  • 자바스크립트와 대부분의 프로그래밍 언어는 렉시컬 스코프를 따름 

 

동적 스코프

  • 함수를 정의할 때에는 함수가 어디에서 호출될 지 알 수 없음
  • 따라서 함수가 호출될 때 상위 스코프가 결정됨