본문 바로가기

JavaScript

[Deep dive] 13장 스코프

13.1 스코프란?

 

스코프(scope)

- 식별자가 유효한 범위 

- 스코프(유효범위)를 통해 식별자인 변수 이름의 충돌을 방지하여 같은 이름의 변수를 사용 가능하게 함

 

식별자 결정 (identifier resolution)

- 자바스크립트 엔진은 이름이 같은 두 개의 변수 중에서 어떤 변수를 참조해야 할 것인지 결정해야함

- 자바스크립트 엔진이 식별자를 검색할 때 사용하는 규칙

- 자바스크립트 엔진은 코드를 실행할 때 코드의 문맥(context)을 고려함

var x = 'global';

function foo() {
  var x = 'local';
  console.log(x); //local
}

foo();

console.log(x); //global

 - 코드의 가장 바깥 영역의 선언된 x 변수는 어디서든 참조 가능

 - foo 함수 내부에 선언된 x 변수는 foo 함수 내부에서만 참조 가능

 

렉시컬 환경 (lexical environment)

- 코드가 어디서 실행되며 주위에 어떤 코드가 있는지

- 코드의 문맥은 렉시컬 환경으로 이뤄짐

- 이를 구현한 것이 실행 컨텍스트(execution context)

 

 

13.2 스코프의 종류 

 

- 코드는 전역(global)과 지역(local)로 구분

구분 설명 스코프 변수
전역 코드의 가장 바깥 영역 전역 스코프 전역 변수
지역 함수 몸체 내부  지역 스코프  지역 변수 
var x = 'global x';
var y = 'global y';

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

  console.log(x); //global x
  console.log(y); //global y
  console.log(z); //outer's local z

  function inner() {
    var x = "inner's local x";

    console.log(x); //inner's local x
    console.log(y); //global y
    console.log(z); //outer's local z
  }

  inner();
}

outer();

console.log(x); //global x
console.log(z); //ReferenceError

 

13.2.1 전역과 젼역 스코프 

 

전역(global)

- 코드의 가장 바깥 영역

- 전역 스코프(global scope)를 만듬

- 전역 변수는 어디서든지 참조 가능

 

 

13.2.2 지역과 지역 스코프 

 

지역(local)

- 함수 몸체 내부 

- 지역 스코프(local scope)를 만듬

- 지역 변수는 자신이 선언된 지역과 하위 지역(중첩 함수)에서만 참조 가능

- 지역 변수는 자신의 지역 스코프하위 지역 스코프에서만 유효 

 

 

13.3 스코프 체인 

 

스코프 체인 (scope chian)

 

- 스코프가 계층적으로 연결된 것

- 모든 스코프는 하나의 계층적 구조로 연결

- 모든 지역 스코프의 최상위 스코프는 전역 스코프

 

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

상위 스코프 방향으로 이동하여 선언된 변수를 검색 (identifier resolution)\

 

- 스코프 체인은 물리적인 실체로 존재

 -> 자바스크립트 엔진은 코드를 실행하기에 앞서 렠시컬 환경을 실제로 생성

 -> 변수 선언이 실행되면 변수의 식별자가 렉시컬 환경에 키(key)로 등록

 -> 변수 할당이 일어나면 렉시컬 환경의 변수 식별자에 해당하는 값을 변경

  

 

 

13.4 함수 레벨 스코프 

 

블록 레벨 스코프 (block level scope)

 - 모든 코드 레벨(if, for, while try/catch등)에서 지역 스코프를 만듬 

 - C, java

 - let, count 키워드 

 

함수 레벨 스코프 (function level scope)

 - var 키워드로 선언된 변수는 오로지 함수의 코드 블록(함수의 몸체)만을 지역 스코프로 인정

 

var x = 1;

if(true) {
  //var 함수 키워드로 선언된 변수는 함수의 코드 블록만을 지역 스코프로 인정
  //함수 밖에서 var 키워드로 선언된 변수는 코드 블록  내에서 선언되었다 할지라도 모두 전역 변수 
  //따라서 x는 전역 변수. 이미 선언된 전역 변수 x가 있으므로 x 변수는 중복 선언
  //의도치 않게 변수 값이 변경되는 부작용
  var x = 10;
}

console.log(x); //10

 

13.5 렉시컬 스코프 

 

동적 스코프 (dynamic scope)

- 함수를 어디서 호출했는지에 따라 함수의 상위 스코프 결정

 

렉시컬 스코프 (lexical scope)

- 함수를 어디서 정의했는지에 따라 함수의 상위 스코프 결정

- 자바스크립트를 비롯한 대부분 프로그래밍언어가 채택 

- 함수의 상위 스코프는 함수 정의가 실행될 때 정적으로 결정

- 함수 정의가 실행되어 생성된 함수 객체는 이렇게 결정된 상위 스코프를 기억

 

var x = 1;

function foo() {
  var x = 10;
  bar(); //bar함수가 호출된 위치 
}

//bar함수가 정의된 위치 
function bar() {
  console.log(x);
}

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

 - bar함수는 전역에서 정의된 함수 

 - 생성된 bar 함수 객체는 전역 스코프를 기억

 - 호출된 곳이 어디인지 관계없이 전역 스코프를 상위 스코프로 사용