JavaScript

[DeepDive] 13장(스코프), 14장(전역 변수의 문제점) 필요 내용 정리

스코프

  • 스코프란, 식별자(변수명)에 접근할 수 있는 유효한 범위를 말한다.
  • 다른 스코프 영역에서 같은 이름의 변수가 존재할 때, 자바스크립트 엔진은 어떤 변수를 참조해야 할 것인지를 결정하게 되는데, 이를 식별자 결정이라고 한다.
var x = "global";

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

foo();

console.log(x); // global

 

스코프의 종류

  • 전역 스코프(global scope)
    • 함수나 특정 블록({})에 속하지 않고 어디든 접근이 가능하며 이때 지정된 변수를 전역변수라 한다. (함수 외부에서 선언된 변수는 무조건 전역변수이다.)
  • 지역 스코프(local scope)
    • 코드 내 특정 영역에만 활동 및 접근이 가능하며 이때 지정된 변수를 지역변수라 한다. 이러한 지역 스코프는 해당 함수 내에서 자유로운 함수 레벨 스코프, {}블록 안에서만 자유로운 블록 레벨 스코프가 속한다.
    • 지역 스코프는 ES6 이전까지는 함수 몸체 내부(함수 스코프)를 통해서만 생성이 가능했지만, ES6 이후로 특정 블록({}) 내에서도 스코프가 생성이 가능해졌다.

 

스코프 체인

  • 스코프가 계층적으로 연결된 것을 스코프 체인이라 한다. (최상위 스코프는 전역 스코프이다.)
  • JS 엔진은, 해당 스코프에서 참조하고자 하는 변수가 없을 경우 스코프 체인을 통해 상위 스코프로 이동하면서 변수를 탐색해나간다.
  • 상위 스코프에서 유효한 변수를 하위 스코프에서 참조할 수 있지만, 반대는 불가하다. (렉시컬 환경, 클로저로 인해 발생하므로 자세한 설명은 해당 섹션에서 적도록 하겠다.)

 

동적 스코프, 렉시컬 스코프

  • 동적 스코프
    • 함수를 어디서 호출했는지에 따라 함수 상위 스코프가 결정되는 방식이다.
  • 렉시컬 스코프(정적 스코프)
    • 함수를 어디서 정의(선언)했는지에 따라 함수 상위 스코프가 결정되는 방식이다.
    • 자바스크립트는 렉시컬 스코프를 따르며 함수가 호출된 위치는 상위 스코프 결정에 어떠한 영향도 주지 않는다.
    • 함수의 상위 스코프는, 함수가 선언된 스코프이다. (예제의 경우, foo, bar 함수 모두 전역 스코프를 상위 스코프로 참조하고 있다.)
const x = 1;

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

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

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

 

변수의 생명 주기

  • 지역 변수
    • 함수의 생명주기와 동일하다.(함수가 호출시 생성, 종료시 소멸)
  • 전역 변수
    • 함수의 호출과 같이 특별한 진입점 없이 코드가 로드되었을 때 바로 실행된다.
    • 전역 변수는 전역 객체의 프로퍼티로서 지정되며, 전역 객체의 생명 주기와 일치하다. (웹 기준 브라우저 종료시까지 계속 존재)

 

전역 변수의 문제점

  • 암묵적 결합
    • 전역 변수로 선언함으로써, 어디서든 참조와 할당이 가능한 변수를 사용할 수 있는 암묵적 결합을 허용하는데, 이러한 전역 변수는 유효 범위가 커 코드의 가독성은 나빠지고 의도치 않은 상태변경으로 인해 위험도가 높아진다.
  • 긴 생명주기
    • 생명 주기가 길기 때문에 메모리 리소스도 오랜기간 소비한다.
  • 스코프 체인상의 최상위 스코프
    • 변수를 검색할 때, 전역 변수가 가장 마지막에 검색된다. (검색 속도가 느리다.)
  • 네임스페이스 오염
    • 파일이 분리되어 있어도 하나의 전역 스코프를 공유하기 때문에, 다른 파일 내에서 동일한 이름으로 선언된 변수 및 함수가 존재할 경우 예상치 못한 결과가 생길 수 있다.