ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [JavaScript] 전역 변수의 문제점
    JavaScript 2022. 7. 8. 00:01
    728x90

    전역 변수의 무분별한 사용은 상당히 위험합니다. 전역 변수를 반드시 사용해야 할 이유를 찾지 못한다면 지역 변수를 사용하는 것이 좋습니다. 전역 변수의 문제점과 전역 변수의 사용을 억제할 수 있는 방법을 살펴보겠습니다.

    변수의 생명 주기

    지역 변수의 생명 주기

    • 생명 주기 : 변수는 생물처럼 생성되고 소멸된다. 그것을 생명 주기라 한다.

    함수 내부에 선언된 지역 변수는 함수가 호출되면 생성하고 함수가 종료하면 소멸한다.

    function foo() {
      var x = 'local';
      console.log(x); // local
      return x;
    }
    
    foo();
    console.log(x); // ReferenceError: x is not defined
    

    여기서 우리는 변수 호이스팅에 의해서 var x가 런타임 이전에 실행 될 것이라고 생각할 수 있지만 그건 전역변수 한정이다. 함수 내부에 선언한 변수는 함수가 호출된 직후에 함수 내부에서 호이스팅 된 후 함수 내부의 코드가 한 줄씩 순차적으로 실행되게된다. 그리고 함수가 종료되면 x 변수도 소멸된다.

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

    1번은 undefined가 출력되게 된다. 앞서 설명했듯이 foo내부에있는 var x = “local”에서 var x가 함수 내부에서 호이스팅 되기 때문이다.

    전역 변수의 생명 주기

    전역 변수는 특별한 진입점이 없이 코드가 로드되자마자 바로 실행된다.(변수 호이스팅)

    var 키워드로 선언한 전역 변수는 전역 객체의 프로퍼티가 된다. 전역 객체 window는 웹페이지를 닫기 전까지 유효하다.

    전역 변수의 문제점

    암묵적 결합

    • 암묵적 결합 : 모든 코드가 변수를 참조하고 변경할 수 있다.

    변수의 범위가 크면 코드의 가독성은 나빠지고 의도치 않게 변경될 수 있는 위험성이 높아진다.

    긴 생명 주기

    전역변수는 생명 주기가 길다. 즉, 메모리 리소스도 오랜 기간 소비한다.

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

    스코프 체인에 의해 가장 마지막에 검색하므로 검색 속도가 가장 느립니다.

    네임스페이스 오염

    자바스크립트는 파일이 분리되어 있어도 전역 스코프를 공유한다는 문제점이 존재한다. 따라서 동일한 이름으로 명명된 변수로 예상치 못한 결과를 가져올 수 있다.

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

    1) 즉시 실행 함수

    즉시 실행 함수는 단 한번만 호출되므로 모든 코드를 즉시 실행 함수로 감싸면 모든 변수는 즉시 실행 함수의 지역 변수가 된다.

    (function () {
      var foo = 10; // 즉시 실행 함수의 지역 변수
      // ...
    }());
    
    console.log(foo); // ReferenceError: foo is not defined
    

    2) 네임스페이스 객체

    네임스페이스를 사용하면 식별자 충돌을 방지할 수 있으나 결국 전역 변수에 할당되므로 그다지 유용하진 않다.

    var MYAPP = {}; // 전역 네임스페이스 객체
    
    MYAPP.person = {
      name: 'Lee',
      address: 'Seoul'
    };
    
    console.log(MYAPP.person.name); // Lee
    

    3) 모듈 패턴

    모듈 패턴은 클래스를 모방해서 관련이 있는 변수와 함수를 모아 즉시 실행 함수로 감싸 하나의 모듈로 만든다. 모듈 패턴은 클로저 기반으로 동작하는데 클로저를 통해 전역 변수를 억제할 수 있다. 클로저에 대해선 추후에 자세히 다뤄보겠다.

    var Counter = (function () {
      // private 변수
      var num = 0;
    
      // 외부로 공개할 데이터나 메서드를 프로퍼티로 추가한 객체를 반환한다.
      return {
        increase() {
          return ++num;
        },
        decrease() {
          return --num;
        }
      };
    }());
    
    // private 변수는 외부로 노출되지 않는다.
    console.log(Counter.num); // undefined
    
    console.log(Counter.increase()); // 1
    console.log(Counter.increase()); // 2
    console.log(Counter.decrease()); // 1
    console.log(Counter.decrease()); // 0
    

    자바스크립트는 public, private, protected등의 접근 제한자를 제공하지 않는다. 모듈 패턴은 전역 네임 스페이스의 오염을 막고, 정보 은닉을 구현하기 위해 사용한다.

    위 예제는 기본적으고 private 변수를 만드맂만 return을 통해 반환 해줄 때만 외부에 노출되는 퍼블릭 멤버가 된다.

    4) ES6 모듈

    ES6 모듈은 파일 자체의 독자적인 모듈 스코프를 제공한다.

    728x90

    댓글

Designed by Tistory.