[Deep Dive] 14장 전역 변수의 문제점
전역변수를 많이 사용하다보면 의도하지 않은 재할당이 일어날 수 있고, 메모리를 잡아먹는 등 문제점들이 있다.
변수의 생명주기
함수 내부에서 변수가 선언될 경우 초기에 전역변수처럼 호이스팅이 일어나지 않는다.
함수가 실했되었을 때 자바스크립트 엔진에 의해서 가장 먼저 실행(선언)된다
const func = () => {
var x = 10;
console.log(x); // 10
}
func();
console.log(x); // error
위 코드를 보게되면 이해하기 쉽다. 우리가 알던대로라면 호이스팅이 일어나서 변수들의 선언이 가장 먼저 실행되어 가장 아랫줄의 console.log(x);
은 undefined
가 되어야 한다. 하지만 함수 내에서 변수를 선언한 경우에는 변수를 실행했을때 함수 내부 코드를 실행하는 측면에서만 가장 먼저 변수 선언이 일어난다
이후 함수를 실행하고 변수가 선언이 되었더라도 함수가 종료되면 변수도 사라지게 된다
➞ 즉 변수의 생명주기는 함수의 생명주기와 일치한다.
전역변수도 마찬가지로 자바스크립트에 의해 어떤 객체보다도 먼저 생성되는 전역 객체의 생명주기와 동일하다
전역 변수의 문제점
암묵적 결합
전역변수는 어디서든 참조하고 할당할 수 있다. 따라서 어디서든지 전역변수를 참조하고 변경할 수 있다. 이처럼 유효 범위가 크면 가독성이 나빠지고 변수관리가 어렵다
긴 생명주기
전역변수의 생명 주기는 전역 객체의 생명주기와 동일하므로 코드 전체의 생명주기와 같다. 따라서 그만큼 시스템 자원(메모리 리소스)을 오래 차지하고 있다는 뜻이 된다.
스코프 체인상 종점에 존재
스코프 체인상에서 보면 거슬러 올라가야 하기 때문에 전역변수를 참조해야 할때 가장 종점까지 거슬러 올라가야 한다. 따라서 그만큼 시간이 오래 걸린다.(큰 차이는 없으나 시간 차이는 존재)
네임스페이스 오염
파일이 분리되어 있더라도 하나의 전역 스코프를 공유한다. 따라서 동일한 이름의 전역변수가 존재할 수 있다.
전역 변수 사용의 억제(방법)
이러한 문제점들을 방지하기 위한 방법들이 있다
즉시 실행 함수
즉시 실행 함수는 한번만 실행되므로 이를 이용해서 변수의 유효 범위를 제한한다(지역변수로)
(function (){
const x = "jongbin";
}());
console.log(x); // error
네임스페이스 객체
전역에 객체를 생성하고 객체 내에 객체를 생성해 계층적으로 관리할 수 있다.
( 중복을 방지할 수 있으나 전역 변수로 선언되는 것은 동일하다 )
const obj = {};
obj.name = "jongbin";
console.log(obj.name);
모듈 패턴
클래스를 모방해서 변수와 함수를 모아 즉시 실행 함수로 감싸 하나의 모듈로써 만든다.
네임스페이스의 오염을 막고, 정보은닉에도 활용된다.
const Mo = (function (){
const name = "jongbin";
return {
hi(){
return name+" Hi!";
}
bye(){
return name+" Bye!";
}
}
}())
console.log(Mo.name); // undifined (정보은닉)
console.log(Mo.hi()); // jongbin Hi!
외부에서 Mo
내부의 name
이라는 변수를 참조할 수 없다
ES6 모듈
파일 자체의 독자적인 모듈 스코프를 제공한다.
(모듈 내에서 var
키워드로 선언한 변수는 전역변수가 아니다)
그렇다면 const, let 키워드는 해당이 안되는건가???
<script type="nodule" src="lib.mjs"></script>
<script type="nodule" src="app.mjs"></script>
ES6의 모듈은 구형 브라우저에서는 작동하지 않는다. 또한 트랜스파일링이나 번들링이 필요하므로 Webpack을 더 사용한다.
* 트랜스파일링: 한 언어로 작성된 소스코드를 비슷한 수준의 추상화(Abstraction)를 가진 다른 언어로 변환하는 것
* 번들링: 여러개의 파일을 모아서 하나로 만드는 것
* Webpack: 오픈 소스 자바스크립트 모듈 번들러
이웅모 선생님의 모던 자바스크립트 Deep Dive를 공부하기 위해 정리한 글입니다.
혹시나 보시다가 고칠 부분이나 마음에 안드시는 부분이 있다면 말씀해주시면 감사하겠습니다!