TIL : 전역변수의 문제점

hihyeon_cho·2023년 2월 1일
0

TIL

목록 보기
62/101
post-thumbnail

변수의 생명주기

: 변수가 선언에 의해 생성되고 할당을 통해 값을 가지며, 그리고 소멸되는 시점까지.

이러한 변수의 생명주기가 없으면 프로그램을 종료하지 않는 한 영원히 메모리 공간을 점유하게 된다.

1. 지역변수의 생명주기

⇒ 함수가 호출되는 시점에 생성되고, 함수가 종료하면 소멸한다. ( = 함수의 생명주기. )

  • 읭? 변수 선언은 런타임 이전에 먼저 실행되잖아요?!
    전역변수에 한정된 얘기 !
       지역변수는 함수가 호출된 직후에 실행된다 !

var x = 'global';

function foo () {
// (1)생성
	console.log(x); // undefined
	var x = 'local'; //(2)할당
// (3)소멸
}

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

2. 전역변수의 생명주기

: 코드가 로드되자마다 곧바로 해석되고 실행되며 더이상 실행할 문이 없을 때 종료됨. ( = 애플리케이션의 생명주기 )

var로 선언된 전역 변수는 전역 객체의 프로퍼티가 된다.
” 전역 변수의 생명주기 = 전역객체의 생명주기 “

  • 전역객체 ?
    global 객체. 코드가 실행되기 전, 자바스크립트 엔진에 의해 어떤 객체보다도 먼저 생성되는 특수한 객체.
    브라우저 환경 전역객체 = window
    ⇒ var로 선언된 전역변수는 window의 프로퍼티
    = ( 웹을 닫을 때까지 유효 )


전역 변수의 문제점

1. 암묵적 결합

전역변수를 선언한다. = 어디서든 참조하고 할당할 수 있는 변수를 사용한다. ( = 변수의 유효범위가 커짐 )

⇒ 코드의 가독성 나빠짐 + 의도치 않게 상태가 변경될 수 있음

2. 긴 생명 주기

생명주기가 길어지면 메모리 리소스도 오랜기간 소비하며 상태를 변경할 수 있는 시간과 기회가 많아짐.
또한 var키워드는 중복 선언을 허용해서 의도치 않은 재할당이 이루어질 위험

3. 스코프 체인 상에서 종점에 존재

변수를 검색할 때, 가장 마지막에 검색되므로 검색 속도가 가장 느림.

4. 네임스페이스 오염

자바스크립트는 하나의 전역 스코프를 공유하기 때문에,
다른 파일 내에 동일한 이름의 전역 변수나 전역함수가 같은 스코프 내에 존재할 경우 문제가 생길 수 있다.



전역변수의 사용을 억제하는 방법

: 되도록 전역 변수를 반드시 사용해야 하는 경우를 제외하고는 지역변수를 사용.

( ⭐️ 변수의 스코프는 좁을수록 좋다. ⭐️ )

1. 즉시 실행 함수

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

( 전역변수를 생성하지 않으므로 라이브러리 등에 자주 사용됨. )

(function(){
	var foo = 10 ; 
}());

console.log(foo); // ReferenceError : foo is not defined

2. 네임스페이스 객체

var MYAPP = {}; // 전역 네임스페이스 객체 생성

MYAPP.person = {
	name : 'Choi',
	address : 'Seoul'
};

MYAPP.person.age = 22;

// 변수를 프로퍼티로 추가

console.log(MYAPP.person.address); // Seoul

당장 식별자 충동을 방지하는 효과는 네임스페이스 객체 자체가 전역변수라 유용한 방법은 아님.

3. 모듈 패턴

모듈패턴은 클래스를 모방해서 관련이 있는 변수와 함수를 모아 즉시실행함수로 감싸 하나의 모듈을 만든다. 이러한 모듈패턴은 클로저를 기반으로 동작하는데, 이는 전역변수를 억제하고, 캡슐화를 구현할 수 있다.

  • 캡슐화 ?
    객체의 상태를 나타내는 프로퍼티와 메서드를 하나로 묶는 것. 객체의 특정 프로퍼티나 메서드를 감추는 정보 은닉 목적으로도 사용한다.

다른 객체지향 프로그래밍언어와는 달리 자바스크립트는 공개범위를 한정하여 외부의 접근으로부터 보호하는 접근 제한자를 제공하지 않음.
⇒ 정보 은닉을 구현하기 위해서 모듈패턴을 사용

  • 접근제한자
publicprivateprotected
외부 접근 O외부 접근 X, 내부 사용 O외부 접근 X, 내부 사용 X
var Counter = (function(){
	var num = 0; //private 변수 ( private member )

	// 외부로 공개할 데이터 or 메서드를 return  ( public member )
	return{
		increase(){
			return ++num;
		},
		decrease(){
			return --num;
		};
	}
}());

console.log(Counter.num); //undefined
console.log(Counter.increase()); // 1
console.log(Counter.decrease()); // 0

4. ES6 모듈 사용

ES6 모듈에서는 파일 자체의 독자적인 모듈 스코프를 제공하기 때문에, var키워드로 선언한 변수는 더는 전역변수가 아니며, window의 프로퍼티도 아니다.

모던브라우저에서는 ES6 모듈을 사용할 수 있다.
script태그에 type="module" 어트리뷰트를 추가하면 로드된 자바스크립트 파일은 모듈로서 동작한다.

<script type="module" src="lib.mjs"></script>
<script type="module" src="app.mjs"></script>

하지만, IE를 포함한 구형 브라우저에서는 동작하지 않기 때문에 아직까지는 Webpack등의 모듈번들러를 사용

profile
코딩은 짜릿해 늘 새로워 ✨

0개의 댓글