모던 자바스크립트 Deep Dive : 14장 전역 변수의 문제점

EdLee·2022년 10월 29일

javascript

목록 보기
4/37

14장 전역 변수의 문제점

1. 변수의 생명주기


변수는 자신이 선언된 스코프에서 생성되고 소멸한다

1.1 지역변수의 생명 주기

  • 지역 변수의 생명 주기는 함수의 생명 주기와 일치한다
var x = 'global';

function foo() {
  console.log(x); // 변수 호이스팅에 의해 x가 선언되어 있다는 점을 잊지 말 것
  var x = 'local'; // 변수 할당은 런타임에 이뤄진다
}

foo(); // undefined
console.log(x); // global

1.2 전역변수의 생명 주기

  • 전역변수의 생명 주기는 전역 객체 window의 생명주기와 일치한다
  • 즉, 웹 페이지가 열린 시점부터 닫힐 때까지😇

2. 전역 변수의 문제점


  1. 암묵적 결합
    스코프를 가리지 않고 모든 코드가 전역 변수에 접근 가능하다.
    따라서 코드 가독성이 나빠지고, 의도치 않은 상태 변경이 이뤄질 수 있다.
  2. 긴 생명 주기
    메모리에 항상 상주하고, 다른 변수와 중복될 가능성도 있다.
  3. 스코프 체인의 종점에 존재
    변수를 검색할 때 가장 마지막에 검색되므로, 속도가 가장 느리다.
  4. 네임스페이스 오염
    js는 파일이 분리되어 있어도, 하나의 html 내에 호출된 모든 js 파일이 같은 전역 스코프를 공유한다.
    따라서 전역변수가 중복될 가능성이 크다.

3. 전역 변수의 사용을 억제하는 방법


전역 변수는 반드시 필요할 때만 사용하고, 항상 지역 변수를 먼저 사용해야 한다. 변수의 스코프는 좁을 수록 좋다.

3.1 즉시 실행 함수

  • 모든 코드를 통째로 즉시 실행 함수로 감싸면, 모든 변수는 즉시 실행 함수의 지역변수가 된다.
  • 전역 변수를 생성하지 않으므로, 라이브러리 간 변수 충돌을 막기 위해 라이브러리 등에 자주 사용되는 방법.

3.2 네임스페이스 객체

  • 전역변수의 대체제로 전역 객체를 만들어 사용한다
var MY_GLOBAL= {};

MY_GLOBAL.teamA= {
  name: 'teamA',
  score: 11
};
MY_GLOBAL.teamB= {
  name: 'teamB',
  score: 4
};

console.log(MY_GLOBAL.teamA.score); // 11
  • 단, 전역 객체도 전역 스코프에 있으므로, 근본적인 해결 방법은 아니다

3.3 모듈 패턴

  • 정보 은닉을 위해 캡슐화를 구현하는 테크닉이지만, 전역 변수를 지양하기 위해서도 사용할 수 있다
  • 클로저를 기반으로 한 동작이므로, 상세한 설명은 24장 참고
var Counter = (function() {
  var num = 0; // private 멤버
  var name = 'Counter';
  return {
    name, // public 멤버
    increase() {
      return ++num;
    },
    decrease() {
      return --num;
    }
  };
}());

console.log(Counter.num); // undefined
console.log(Counter.name); // Counter
console.log(Counter.increase()); // 1
console.log(Counter.increase()); // 2
console.log(Counter.decrease()); // 1
console.log(Counter.decrease()); // 0

3.4 ES6 모듈

  • ES6 모듈을 사용하면, 각 js 파일 별로 모듈화된다
  • 자세한 것은 48장, 49장 참고
<script type="module" src="myModule.js"></script>
// 이제 myModule.js는 모듈로서 동작한다
// 다른 파일에서 불러오려면, import나 require 키워드가 필요하다
// myModule.js는 독자적인 모듈 스코프를 가진다

※ mjs와 js의 차이는 다음 글 참조 : https://ui.toast.com/weekly-pick/ko_20190805

0개의 댓글