JS | 전역 변수 멈춰 🖐

sol ahn·2021년 11월 28일
0

JavaScript

목록 보기
7/8
post-thumbnail
post-custom-banner

전역 변수의 문제점

전역 변수

전역 변수는 전역 코드에서 선언된 변수

전역 변수의 생명 주기는 어플리케이션의 생명 주기와 같음. cf) 지역 변수의 생명 주기는 함수의 생명 주기와 같음.

var x = 'global'; // 전역 변수

function foo () {
	console.log(x); // 지역 변수 x의 호이스팅으로 인해 undefined 출력
	var x = 'local'; // 지역 변수
}

foo();
console.log(x); // global 출력

var 키워드로 선언한 전역 변수는 전역 객체의 프로퍼티가 됨. ⇒ var 키워드로 선언한 전역 변수의 생명 주기는 '전역 객체'의 생명 주기와 같음.

암묵적 결합(Implicit Coupling)

'암묵적 결합'이란 모든 코드가 전역 변수를 참조하고 변경할 수 있도록 허용하는 것.

변수의 유효 범위가 커질수록 코드의 가독성이 나빠지고 의도치 않게 상태가 변경될 수 있는 가능성이 높아짐.

긴 생명주기

전역 변수는 생명주기가 길기 때문에 메모리 리소스를 오랫동안 차지함.

var 키워드로 선언한 변수는 재할당 허용 ⇒ 전역 변수는 변수 이름이 중복되어 의도치 않게 재할당이 이뤄질 가능성이 있음.

스코프 체인의 말단에 존재

전역 변수는 스코프 체인 상에서 가장 말단에 존재함. ⇒ 스코프 체인을 통해 변수를 검색할 때, 전역 변수의 검색 속도가 가장 느림.

네임스페이스(Namespace) 오염

자바스크립트에서는 파일이 분리되어 있어도 하나의 전역 스코프를 공유함. ⇒ 다른 파일 내에서 같은 이름으로 선언한 전역 변수나 전역 함수가 같은 스코프에 존재하게 되면 예상하지 못한 에러를 발생시킬 수 있음.

네임스페이스(Namespace) : 이름공간, 개체를 구분할 수 있는 범위를 의미함. 하나의 네임스페이스에서 하나의 이름이 단 하나의 개체만을 가리킴.

⛔️ 전역 변수의 사용을 방지할 수 있는 방법

전역 변수의 무분별한 사용은 아주 위험함!

반드시 전역 변수를 사용해야 하는 경우가 아니라면 지역 변수를 사용해야 함. ⇒ 변수의 스코프는 좁을수록 좋음!

즉시 실행 함수(Immediately-Invoked Function Expression)

즉시 실행 함수는 단 한 번만 호출됨.

코드를 즉시 실행 함수로 감싸면 모든 변수는 즉시 실행 함수의 지역 변수가 됨.

(function () {
	var a = 1;
	// ...
}());

console.log(a); // ReferenceError

네임스페이스 객체(Namespace Object)

네임스페이스 객체를 생성하고 전역 변수처럼 사용하고 싶은 변수를 프로퍼티로 추가하는 방법.

❗️ 네임스페이스를 분리하면 식별자 충돌을 방지할 수 있지만, 네임스페이스 객체 자체가 전역 변수에 할당됨.

var NAMESPACE = {};
NAMESPACE.name = 'Sol';

console.log(NAMESPACE.name); // Sol 출력

// ---------------------------------------------

NAMESPACE.person = {
	name: 'Sol',
	age: 20
};

console.log(NAMESPACE.person.name); // Sol 출력

모듈 패턴(Module Pattern)

클래스를 모방해서 관련 있는 변수와 함수를 모아 즉시 실행 함수로 감싸서 하나의 모듈을 생성함.

자바스크립트의 모듈 패턴은 클로저 를 기반으로 동작함. ⇒ '캡슐화(encapsulation)' 구현 가능

자바스크립트에서는 접근 제한자를 제공하지 않기 때문에 모듈 패턴을 사용하여 '정보 은닉'을 구현함.

var Counter = (function () {
	var num = 0; // private 변수
	
	// 외부로 공개할 데이터나 메서드를 프로퍼티로 추가한 객체
	return {
		increase() {
			return ++num;
		},
		decrease() {
			return --num;
		}
	};
}());

console.log(Counter.num); // undefined => num 변수는 외부로 노출되지 않음.
console.log(Counter.increase()); // 1
console.log(Counter.decrease()); // 0

ES6 모듈

ES6 모듈은 파일 자체의 독자적인 모듈 스코프를 제공하기 때문에 전역 변수를 사용할 수 없음.

❗️ ES6 모듈은 구현 브라우저에서는 동작하지 않으며, 사용하더라도 트랜스파일링이나 번들링이 필요하므로 아직까지는 웹팩 등 모듈 번들러를 사용하는 것이 일반적임.


Ref

[도서] 이웅모, ⌜모던 자바스크립트 Deep Dive⌟, 위키북스, 2020

profile
아는 만큼 재밌는 개발자 🤓
post-custom-banner

0개의 댓글