개발 공부/JavaScript
[Javascript] 전역변수와 지역변수
U_D
2022. 11. 27. 23:11
전역변수? 지역변수?
전역 변수와 지역변수는 선언되는 위치에 따라 결정된다.
- 지역변수는 중괄호({}) 안 즉, 함수 내부에서 선언되며 선언된 지역에서만 유효한 변수다.
- 전역변수는 특정 지역(중괄호) 밖에서 즉, 외부에서 선언 되며 이 변수는 지역과 관계없이 어느 곳에든 유효하다.
다음은 전역변수와 지역변수의 코드 예시이다.
오히려 글보다는 코드로 볼 때 이해가 빠른거 같다.
var x = "global"; //전역변수
function foo() {
console.log(x);
var x = "local" //지역변수
}
foo();
console.log(x); //global
전역변수와 지역변수는 상황에 따라 선택을 해야하지만 전역변수는 반드시 사용해야 할 이유가 있을 때 쓰는것이 좋다.
그 이유는 다음과 같은 문제점을 가지고 있어서이다.
전역변수의 문제점
1) 암묵적 결합과 중복 선언
- 모든 코드가 전역변수를 참조하고 변경할 수 있도록 아묵적으로 결합되어 있어, 의도치 않게 변경이 일어나도 어디서 변경이 일어났는지 알기가 힘들며 그에 따라 코드의 가독성이 나빠진다.
2) 긴 생명주기
- 전역변수는 생명주기가 길어 메모리 리소스를 오래동안 소비한다.
- 생명주기가 길다보니 변수가 변경될 수 있는 시간도 길다는 의미로 의도치 않은 재할당 과정이 생길 수 도 있다.
3) 스코프 체인 상에서 종점에 존재
- 전역 변수는 스코프 체인 상의 종점에 존재하기 때문에 변수를 검색할 대 가장 마지막에 검색이 됨으로 검색 속도가 느림을 의미한다.
4) 네임 스페이스 오염
- 파일이 분리되어 있어도 하나의 전역 스코프를 공유함으로 다른 파일에서도 같은 이름으로 선언된 전역 변수가 있다면 예상치 못한 결과를 가져올 수 있다.
전역변수 억제 방법
이렇듯 무분별한 전역변수의 사용은 위험하다. 최대한 변수의 스코프는 좁을 수록 좋으며 전역변수 사용을 억제할 수 있는 방법으로 다음과 같은 내용이 있다.
1) 즉시 실행 함수
- 함수 정의와 동시에 호출되는 즉시 실행 함수는 단 한번만 호출됨으로 모든 코드를 즉시 실행 함수로 감싸면 지역변수로 활용이 가능하다. 이를 통해 전역변수의 사용을 제한하는 방법이다.
2) 네임스페이스 객체
- 전역에 네임스페이스 역할을 담당할 객체를 생성하고 전역변수로 활용하고 싶은 변수를 추가하는 방법이다. 아래 코드를 보면 조금 더 이해가 잘 될 것이라 생각된다.
- 예시 코드
var MYAPP = {}; //전역네임스페이스 객체
MYAPP.name = 'RYU';
console.log(MYAPP.name) //RYU
3) 모듈 패턴
- 모듈 패턴이란 관심도가 같은 변수와 함수를 모아 즉시 실행 함수로 감싸 하나의 공통적인 모듈로 만드는 것이다.
- 모듈 패턴은 클로저 개념을 기반으로 진행된다.
*클로저 : 선언되는 당시의 환경 즉, 위치를 기억하는 것 - 예시 코드
var Counter = (function () {
//private 변수
var num = 0;
//외부로 공개할 데이터나 메서드를 프로퍼티로 추가한 객체를 반환
return {
increase() {
return ++num;
},
decrease() {
return --num;;
}
}
4) ES6 모듈
- ES6 모듈은 파일 자체의 독자적인 모듈 스코프를 제공한다.
- 그렇기에 var 선언을 사용해도 전역 변수가 아니게 된다.
- 예시 코드
<script type="module" src="lib.mjs"></script>
<script type="module" src="app.mjs"></script>
어떻게 보면 var를 활용한 변수 선언을 쓰고 있지 않지만 var를 통한 전역변수의 활용이 사이드 이펙트나 휴먼에러가 많이 발생 할 수 있었겠다는 생각이 들었다. 이러한 개념을 알고 있는 상태에서 let, const 또는 함수 선언들을 하게되면 확실히 조금은 더 생각하며 코드를 칠 수 있을거 같다.