티스토리 뷰

14장. 전역 변수의 문제점

  • global object
    • 클라이언트 사이드 환경(브라우저): window
    • 서버 사이드 환경(Node.js): global
    • ES11 에서 globalThis 로 통일됨.
  • 전역 변수 단점
    • 암묵적 결합(implict coupling): 유효 범위가 너무 커 가독성이 나쁘고 상태 변경의 위험이 높음.
    • 긴 생명 주기: 메모리 리소스 오랜 기간 소비
    • 스코프 체인 상에서 종점에 존재: 변수 검색시 가장 마지막에 검색된다는 뜻. 즉, 검색 속도가 가장 느리다.
    • 네임스페이스 오염: 여러 파일에서 하나의 전역 스코프를 공유한다. 예상치 못한 결과 확률 높음.

 

전역 변수 사용 억제 방법

  • 변수의 스코프는 좁을수록 좋다.
  1. 즉시 실행 함수
    1. 즉시 실행 함수를 사용하면 지역 변수가 된다.
    (function () {
    	var foo = 10;
    	// ...
    }());
    
    console.log(foo);
    
  2. 네임스페이스 객체
    1. 네임스페이스 역할 담당할 객체 생성하고 전역 변수처럼 사용하고 싶은 변수를 프로퍼티로 추가하는 방법
    2. 근데 굳이 이렇게 써야할까...? 란 생각이 드는군..
    // 전역 네임스페이스 객체
    var MYAPP = {}; 
    MYAPP.name = 'Lee';
    
    console.log(MYAPP.name); // Lee
    
    // 계층적 구성
    var MYAPP = {};
    NYAPP.person = {
    	name: 'Lee',
    	address: 'Seoul',
    };
    
    console.log(MYAPP.person.name); // Lee
    
  3. 모듈 패턴
    1. 클래스를 모방해서 관련이 있는 변수, 함수를 모아 즉시 실행 함수로 감싸 하나의 모듈을 만든다.
    2. 클로저를 기반으로 동작
    3. 이것도 마찬가지로 이렇게 까지 써야할까 란 생각이 드는데... 잘 모르겠다.
    var Counter = (function() {
    	// private 변수
    	var num = 0;
    	
    	// 외부로 공개할 데이터나 메서드를 프로퍼티로 추가한 객체를 반환한다.
    	return {
    		increase() {
    			return ++num;
    		},
    		decrease() {
    			return --num;
    		}
    	};
    }());
    
    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
    
  4. ES6 모듈
    1. ES6 모듈은 파일 자체의 독자적인 모듈 스코프를 제공한다.
    // type="module" 추가, 확장자는 mjs 권장
    <script type="moudle" src="lib.mjs"></script>
    <script type="moudle" src="app.mjs"></script>
    

 

대부분의 좋은 코드를 쓰는 법이라고 설명하는 곳에서 변수의 범위를 좁게하라고 하고 글에서도 JS에서도 그렇고 어떻게 피해야하는지를 설명한다. 물론 예측 가능하게 동작하기 위해서는 바뀔 위험이 적어야겠지..