14. 전역 변수의 문제점
1) 변수의 생명 주기
- 변수는 생성, 소멸되는 생명 주기(Life cycle)를 가짐
- "자신이 선언된 위치"에서 생성, 소멸되는데 따라서 전역 변수는 애플리케이션 생명 주기를 갖고, 지역 변수는 함수 생명 주기를 가짐
function foo() {
var x = 'local';
console.log(x); // local
return x;
}
foo();
console.log(x); // ReferenceError: x is not defined
//지역 변수 x는 foo 함수가 호출되어 실행되는 동안에만 유효함
- 단, 지역 변수의 경우 해당 함수 스코프가 어딘가에서 계속 참조 중이라면 사라지지 않음
- 호이스팅이란 변수 선언이 스코프의 선두에 이루어지는 것을 뜻하며, 자바스크립트 엔진에 의해 전역 변수는 실행 전 제일 먼저, 지역 변수는 함수 내부에서 제일 먼저 선언이 이루어짐
var x = 'global';
function foo() {
console.log(x); // undefined - 호이스팅에 의해 변수의 선언만 이루어진 상태
var x = 'local';
}
foo();
console.log(x); // global
- 특히 전역 변수는 var 키워드로 선언된 경우, 전역 객체의 프로퍼티가 되어 전역 객체의 생명 주기를 가지게 됨
- 전역 객체란 코드 실행 전 자바스크립트 엔진에 의해 가장 먼저 생성되는 특수한 객체로, 클라이언트 사이드 환경(브라우저)에서는 window, 서버 사이드 환경(Node.js)에서는 global 객체를 의미
2) 전역 변수의 문제점
1. 암묵적 결합
- 모든 코드가 전역 변수를 참조, 변경 가능하게 되는 것을 뜻함
- 코드의 가독성이 나빠지고, 상태 변경의 위험성 높아짐
2. 긴 생명 주기
- 전역 변수는 생명주기가 길기 때문에 상태 변경에 의한 오류가 발생할 확률 높아짐
3. 스코프 체인 상에서 종점에 존재
- 전역 변수는 스코프 체인 상에서 종점에 존재하기 때문에, 가장 마지막에 검색되므로 검색 속도가 제일 느리다고 할 수 있음
4. 네임스페이스 오염
- 전역 변수는 파일이 달라도 전체가 공유함
- 동일 이름의 전역 변수나 함수가 존재할 위험성 존재
3) 전역 변수의 사용을 억제하는 방법
- "전역 변수를 반드시 사용해야 할 이유를 찾지 못한다면 지역 변수를 사용해야 한다."
1. 즉시 실행 함수
- 모든 코드를 즉시 실행 함수 블록으로 감쌈 -> 전역 변수 사라짐
(function () {
var foo = 10; // 즉시 실행 함수의 지역 변수
// ..
}());
console.log(foo); // ReferenceError: foo is not defined
2. 네임스페이스 객체
- 네임스페이스의 역할을 하는 객체에 전역 변수처럼 사용하고 싶은 변수를 프로퍼티에 추가
var MYAPP = {}; // 전역 네임스페이스 객체
MYAPP.name = 'Lee';
console.log(MYAPP.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
4. ES6 모듈
- 전역 변수 사용이 불가함
- 독자적 모듈 스코프를 제공
- 모듈 어트리뷰트를 추가하여 사용 가능하며 구형 브라우저는 사용이 불가함
<script type="module" src="lib.mjs"></script>
<script type="module" src="app.mjs"></script>
- 일반적으로 브라우저보다 웹팩 등의 모듈 번들러를 사용
참고 : 도서 <모던 자바스크립트 Deep Dive>
'TIL' 카테고리의 다른 글
<모던 자바스크립트 Deep Dive> 15장 let, const 키워드와 블록 레벨 스코프 요약 (2) (0) | 2022.02.22 |
---|---|
<모던 자바스크립트 Deep Dive> 15장 let, const 키워드와 블록 레벨 스코프 요약 (1) (0) | 2022.02.21 |
<모던 자바스크립트 Deep Dive> 13장 스코프 요약 (0) | 2022.02.15 |
<모던 자바스크립트 Deep Dive> 12.5~12.7장 함수 요약 (0) | 2022.02.14 |
<모던 자바스크립트 Deep Dive> 11~12.4장 원시 값과 객체의 비교, 함수 요약 (0) | 2022.02.08 |