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

둡둡·2024년 1월 10일

Modern Javascript Deep Dive

목록 보기
15/49

14.1. 변수의 생명 주기

14.1.1. 지역 변수의 생명 주기

  • 변수는 선언으로 생성되고 할당을 통해 값을 갖고, 소멸되는 생명 주기(life cycle)가 있음
    • 자신이 선언된 위치에서 생성되고 소멸함
    • 변수 호이스팅은 전역 변수에 한정
  • 지역 변수의 생명 주기는 함수 생명 주기와 일치함
    • 지역 변수는 해당 변수가 속한 코드 블록이 실행될 때 생성됨
  • 변수의 생명 주기는 메모리 공간이 확보된 시점부터 해제되어 가용 메모리 풀에 반환되는 시점까지
    • 할당된 메모리 공간은 메모리 공간을 참조하지 않을 때 해제됨
  • 호이스팅은 스코프 단위로 동작함

14.1.2. 전역 변수의 생명 주기

  • 전역 변수의 생명 주기는 전역 객체의 생명 주기와 일치함
    • 전역 객체: 가장 먼저 생성되는 특수한 객체
      • 클라이언트 사이드 환경(브라우저)에서는 window
      • 서버 사이드 환경(Node.js)에서는 global

14.2. 전역 변수의 문제점

암묵적 결합

  • 모든 코드가 전역 변수를 참조하고 변경할 수 있음
  • 변수의 유효 범위가 클수록 코드의 가독성이 낮음
  • 상태 변경에 대한 위험성도 높아짐

긴 생명 주기

  • 메모리 리소스를 오래 소비함
  • 변수 이름 중복 가능성 높음, 의도치 않은 재할당

스코프 체인 상에서 종점에 존재

  • 변수를 검색할 때 가장 마지막에 검색됨 -> 검색 속도가 가장 느림

네임스페이스 오염

  • 중복 이름 등으로 인해 예상치 못한 결과 발생

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

  • 전역 변수를 반드시 사용할 이유가 없다면 사용 지양

14.3.1. 즉시 실행 함수

  • 함수 정의와 동시에 단 한 번만 호출되는 함수
  • 모든 코드를 즉시 실행 함수로 감싸면 모든 변수는 함수의 지역 변수가 됨
  • 라이브러리 등에서 주로 사용

14.3.2. 네임스페이스 객체

  • 전역에 네임스페이스 역할의 객체를 생성하고, 필요한 변수를 프로퍼티로 추가하는 방법
var MYAPP = {}; // 전역 네임스페이스 객체

MYAPP.name = ‘Park’;
console.log(MYAPP.name); // Park

14.3.3 모듈 패턴

  • 클래스를 모방하여, 관련 있는 변수와 함수를 하나의 즉시 실행 함수로 감싸 모듈로 만드는 패턴
  • 클로저 기반으로 동작
    • 클로저: 함수가 선언된 렉시컬 환경과 함수의 조합
    • 클로저 환경에서는 생성된 시점에서 유효한 지역 변수로 구성됨
function makeFunc() {
  const name = “Hello, JavaScript”;
  function displayName() {
    console.log(name);
  }
  return displayName;
}
 
const myFunc = makeFunc(0;
myFunc(); // Hello, JavaScript
// name은 makeFunc() 함수의 지역 변수로 undefined로 나올 것으로 예상하지만,
// 클로저 환경을 통해 함수 내부에서 유효한 지역 변수인 name이 반환됨 
  • 캡슐화(정보 은닉) 가능
    • 자바스크립트는 public, private 등과 같은 접근 제한자가 없어 대체 가능
    • 외부에 노출하려는 변수나 함수만 반환할 수 있음 (public member)
    • return 에 추가하지 않으면 private 변수가 되어 노출되지 않음
var Counter = (function() {
  var num = 0; // private 변수
  
  // 외부로 리턴하여 사용할 수 있는 객체나 함수
  return {
    increate() {
      return ++num;
    },
    decrease() {
      return --num;
    }
  };
}());

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

14.3.4 ES6 모듈

  • ES6 모듈은 파일 자체에서 독자적인 모듈 스코프를 제공함
  • script type=“module” 어트리뷰트 추가, 확장자 mjs 권장
  • 일반적으로 브라우저보다는 Webpack 등의 모듈 번들러 사용

    [출처] 모던 자바스크립트, Deep Dive

profile
괴발개발라이프

0개의 댓글