본문 바로가기

study/JavaScript

Js - 스코프(Scope)

목차

1. 스코프란
2. 전역 스코프, 지역 스코프, 블록 레벨 스코프, 함수 레벨 스코프
3. 스코프 예시
4. 스코프 체인(Scope Chain)
5. 함수의 상위 스코프 결정
6. 함수의 실행

 

1. 스코프란

  • 자신이 선언된 위치에 따라 본인의 유효범위가 결정된다.
  • 변수 이름, 함수 이름, 클래스 이름과 같은 식별자가 자신이 선언된 위치에 따라 다른 코드에서 자신이 참조될 수 있을지 없을지 결정되는 것이다.

 

2. 전역 스코프, 지역 스코프, 블록 레벨 스코프, 함수 레벨 스코프

  • 자바스크립에서는 전역, 지역 스코프가 존재한다.
  • 전역 스코프
    • 전역에 선언되어 있어 어느 곳에서든지 해당 변수에 접근할 수 있다.

 

  • 지역 스코프
    • 해당 지역 스코프에서만 접근할 수 있으며, 지역을 벗어난 곳에서는 접근할 수 없다.
    • 블록 레벨 스코프, 함수 레벨 스코프 등이 있다.

 

  • 블록 레벨 스코프
    • 코드 블록 {} 내에서만 참조(접근) 가능한 범위를 말한다.
    • if문, for문, 함수 등등
    • c언어 등 대부분 프로그래밍 언어에서 사용된다. Js도 let, const 키워드를 사용하면 블록 레벨 스코프가 가능하다.

 

  • 함수 레벨 스코프
    • Js에서 var 키워드로 선언된 변수는 오로지 함수 코드 블록만을 지역 스코프로 인정한다.

 

 

3.1 스코프 예시 1)

일반적인 경우 아래 코드와 같이 스코프를 우선시하여 결과가 나타난다.

var a = 1; // 전역 스코프

function hello() { // 지역 스코프
  var a = 2;
  console.log(a); // 2
}

hello();
console.log(a); // 1

만약 hello 함수 안에있는 2로 할당된 a 변수가 존재하지 않는다면 어떻게 될 것인가?

 

 

3.2 스코프 예시 2)

hello 함수 안에있는 2로 할당된 a 변수가 존재하지 않는다면 hello 함수 안에있는 로그는 전역 변수의 a를 참조할 것이다.

var a = 1; // 전역 스코프

function hello() {
  console.log(a);
}

hello(); // 1

이러한 이유는 스코프 체인(Scope Chain)에 의해 일어나는 현상이다.

 

 

4. 스코프 체인(Scope Chain)

  • 스코프는 계층적인 구조를 가지고 있으며, 서로 연결 되어있다.
  • 해당 스코프에서 사용하고자 하는 변수가 없다면 Js 엔진은 상위 스코프를 찾아 해당 변수를 찾아간다. 상위 스코프에도 없으면 더 상위 스코프로 찾으러 간다.(전역 스코프까지 갔음에도 변수를 찾지 못했다면 참조 오류가 발생한다.)

 

5. 함수의 상위 스코프 결정

  • 상위 스코프를 결정하는 방법은 동적 스코프, 렉시컬 스코프 이 두가지가 있다.
  • Js는 렉시컬 스코프를 따르므로 함수를 선언한 시점에서 상위 스코프가 결정된다. 함수를 어디에서 호출하였는지는 스코프 결정에 영향을 미치지 않는다.
  • 동적 스코프
    • 함수를 어디서 호출 하였는지에 따라 상위 스코프를 결정한다.

 

  • 렉시컬 스코프(정적 스코프)
    • 함수를 어디서 선언 하였는지에 따라 상위 스코프를 결정한다.
    • Js는 렉시컬 스코프를 따른다.

 

var x = 1;

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

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

foo(); // 1, foo함수 내부에서 호출되는 bar함수는 렉시컬 스코프와 스코프 체인으로 인해 상위 스코프(전역스코프)의 x를 참조한다.
bar(); // 1, 스코프 체인을 통해 출력

 

 

6. 함수의 실행

  1. 함수가 선언되면 내부 슬롯에 상위 스코프에 대한 참조를 저장한다.
  2. 함수가 호출되면 Js엔진의 Call Stack에 실행 컨텍스트를 Push한다.
  3. 렉시결 환경을 생성한다.
    • 렉시컬 환경이란 어떠한 코드가 어디서 실행되고 해당 함수 주변에 어떤 정보가 있는지를 담고 있는 환경이다.
    • 렉시컬 환경은 함수 본인 내부의 식별자 그리고 식별자에 바인딩 된 값들을 기록하고 있는 하나의 자료구조이다.
  4. 함수 내부의 코드 실행이 끝나면 Call Stack에서 해당 함수의 실행 컨텍스트를 Pop한다.