13 스코프

스코프

  • 모든 식별자(변수 이름, 함수 이름, 클래스 이름 등)는 자신이 선언된 위치에 의해 다른 코드가 식별자 자신을 참조할 수 있는 유효범위가 결정됨 -> 식별자가 유효한 범위

렉시컬 환경(lexical environment) : 코드가 어디서 실행되며 주변에 어떤 코드가 있는지 판단
코드의 문맥(context) : 렉시컬 환경으로 이루어짐
실행 컨텍스트(execution context) : 구현문

  • 식별자: 어떤 값을 구별하여 식별해낼 수 있는 고유한 이름 (유일함(unique))
function foo() {
  var x = 1;
  var x = 2;
  console.log(x); //2
}

function bar() {
  let y = 1;
  // let이나 const 키워드로 선언된 변수는 같은 스코프에서 중복 선언을 허용하지 않음
  let y = 2; // SyntaxError
}
bar(); 

1. 스코프의 종류

전역과 전역 스코프

  • 전역
    - 코드의 가장 바깥 영역
    - 스코프 : 전역 스코프
    - 변수 : 전역변수

    전역 변수는 어디서든지 참조할 수 있음

지역과 지역 스코프

  • 지역
    - 함수 몸체 내부
    - 스코프 : 지역 스코프
    - 변수 : 지역변수
    지역 변수는 자신의 지역 스코프와 하위 지역 스코프에서 유효
// 전역 스코프
var x = 'global x';
var y = 'global y';

function outer() {
  // 지역 스코프
  var z = 'outer local z';
  console.log(x); // global x
  console.log(y); // global y
  console.log(z); // outer local z
  
  function inner() {
    // 지역 스코프
  	var x = 'inner local x';
    
    console.log(x); // inner local x
    console.log(y); // global y
    console.log(z); // outer local z
  }
  
  inner();
}

outer();

console.log(x); // global x;
console.log(z); // ReferenceError : z is not defined 

2. 스코프 체인

  • 함수는 중첩될 수 있으므로 함수의 지역 스코프도 중첩가능
    -> 스코프가 함수의 중첩에 의해 계층적 구조를 갖음
  • 스코프 체인(scopre chain) : 스코프가 계층적으로 연결
  • 변수를 참조할 때 스코프 체인을 통해 변수를 참조하는 코드의 스코프에서 시작하여 상위 스코프 방향으로 이동하여 선언된 변수를 검색함
  • 상위 스코프에서 유효한 변수는 하위 스코프에서 자유롭게 참조 가능 하지만 하위 스코프에서 유효한 변수를 상위 스코프에서 참조 불가능
  • 스코프 체인으로 연결된 계층적 구조는 부자 관계로 이뤄진 상속과 유사함
스코프 체인에 의한 함수 검색
function foo() {
  console.log('global function foo');
}

function bar() {
  function foo() {
    console.log('local function foo');
  }
  foo(); // local function foo
}

bar();

함수 레벨 스코프

  • 지역은 함수 몸체 내부를 뜻하고 지격 스코프를 만듬 : 코드 블록이 아닌 함수에 의해서만 지역 스코프가 생성

블록 레벨 스코프(block level scope) : 함수 몸체만이 아니라 모든 코드 블록(if, for, while, try/catch)
함수 레벨 스코프(function level scope) : var 키워드로 선언된 변수는 오로지 함수의 코드 블록(몸체)만을 지역스코프로 인정

// ex1)
var x = 1;
if (true) {
  // var로 선언된 변수는 함수의 코드 블록만을 지역 스코프로 인정
  // 함수 밖에서 var 키워드로 선언된 변수는 코드 블록 내에서 선언되었어도 모두 전역 변수임
  // 의도치 않게 변수 값이 변경되는 부작용 발생
 var x = 10;
}
console.log(x); // 10

// ex2)

var i = 10;
// for문에 선언한 i는 전역변수, 이미 선언된 i가 있으므로 중복 선언
for (var i = 0; i < 5; i++) {
 console.log(i); // 0 1 2 3 4
}
//의도치 않게 변수의 값이 변경됨
console.log(i); // 5

렉시컬 스코프

  • 함수를 어디서 호출했는지가 아니라 함수를 어디서 정의했는지에 따라 상위 스코프를 결정
  • 함수가 호출된 위치는 상위 스코프 결정에 어떤 영향을 주지 않음
  • 함수의 상위 스코프는 언제나 자신이 정의된 스코프
  • 함수의 상위 스코프는 함수 정의가 실행될 때 정적으로 결정됨
var x = 1;
function foo() {
 var x = 10;
 bar();
}

function bar() {
 console.log(x);
}

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


📖 참고도서 : 모던 자바스크립트 Deep Dive 자바스크립트의 기본 개념과 동작 원리 / 이웅모 저 | 위키북스

좋은 웹페이지 즐겨찾기