전역 변수 문제점, 억제하는 방법

boyeonJ·2023년 6월 26일
0

JavaScript Basic

목록 보기
12/24
post-thumbnail

전역 변수는 무분별한 사용이 위험합니다. 따라서 반드시 사용해야할 이유를 찾기 못했다면 지역 변수를 써야 합니다. 오늘은 전역변수의 문제점억제할 수 있는 방법에 대해 알아보려고 합니다.


변수의 생명주기

변수는 생성되고 소멸되는 생명주기를 가집니다. 변수의 생명주기는 메모리 공간이 확보된 시점부터 메모리 공간이 해제되어(가비지 콜렉터에 의하여) 가용 메모리 풀에 반환되는 시점까지를 의미합니다.

전역 변수는 애플리케이션의 생명 주기와 같고, 지역 변수는 그 함수(또는 문)의 생명주기와 같습니다.

함수의 생명주기와 같은 것인지, 문의 생명주기와 같은 것인지는 let/const과 var 키워드로 구문 됩니다. 🔎 자세히 알아보기

1. 전역변수의 생명주기

결국 전역 변수는 애플리케이션의 생명 주기가 같다는 말은, 프로그램을 종료하지 않는 한 영원히 메모리 공간을 점유하게 된다는 말과 같습니다. 따라서 특별한 진입점 없이 코드가 로드되자마자 곧바로 해석되어 실행되고, 더 이상 실행할 문이 없을 때 종료됩니다.

전역 변수의 초기화와 관련된 동작은 브라우저 환경과 Node.js 환경에서 약간 다를 수 있습니다.

  1. 브라우저 환경:

    • 브라우저에서는 웹 페이지를 종료할 때 전역 변수가 초기화됩니다.
    • 웹 페이지를 새로고침하거나 닫거나, 다른 페이지로 이동하는 경우에도 전역 변수는 초기화됩니다.
    • 이러한 동작은 브라우저의 새로운 세션 또는 페이지 간의 독립성을 유지하기 위한 목적으로 설계되었습니다.
  2. Node.js 환경:

    • Node.js 애플리케이션에서는 전역 변수가 애플리케이션의 종료 시점에 초기화되지 않습니다.
    • Node.js 프로세스는 애플리케이션 실행을 위해 계속 실행되는 동안 전역 변수는 유지됩니다.
    • 전역 변수의 생명주기는 Node.js 프로세스의 생명주기와 일치하므로, 애플리케이션이 종료되거나 Node.js 프로세스가 강제로 종료되면 전역 변수도 초기화됩니다.
    • 종료 이벤트 핸들러를 사용하여 Node.js 애플리케이션이 종료될 때 필요한 정리 작업을 수행할 수 있습니다.

요약하면, 브라우저 환경에서는 웹 페이지의 종료에 따라 전역 변수가 초기화되지만, Node.js 환경에서는 애플리케이션 종료 또는 Node.js 프로세스 종료 시 전역 변수가 초기화됩니다.

또한 전역 변수는(var로 생성한) 전역 객체의 프로퍼티가 되는데, 이 또한 전역 변수의 생명주기가 전역 객체의 생명주기와 일치하다는 것을 의미합니다.

전역 객체란?
어떤 객체보다 먼저 생성되는 특수한 객체.

  • 브라우저(CS) : window
  • node.js(SS) : global
    전역 객체의 프로퍼티
  • 표준 빌트인 객체
  • 환경에 따른 호스트 객체
  • var 키워드로 선언한 전역 변수와 전역 함수

    그런데 여기서 let, const로 생성된 전역변수는 전역객체의 프로퍼티가 안됨(block scope라서)

2. 지역변수의 생명주기

  • 함수가 호출된 직후에 함수 몸체의 코드가 한줄씩 순차적으로 실행되기 이전에 자바스크립트에 의해 먼저 실행됩니다.(함수 내부에서의 호이스팅)
  • 지역 변수는 함수가 생성한 스코프(렉시컬 환경)에 등록됩니다.
  • 지역 변수는 스코프가 소멸(메모리 해제)될때까지 유효합니다.
var x = 'global';

function foo() {
  	//호이스팅은 스코프 단위로 동작하기 때문에 x는 undefined
	console.log(x);
  	var x = 'local';
}

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

렉시컬 환경은 물리적인 실체가 있다.


전역 변수의 문제점

암묵적 결합

전역 변수는 전역 변수를 참조하는 모든 코드가 변경할 수 있는 가능성을 주는 암묵적 결합을 허용한다. 변수는 유효범위가 클 수록 가독성이 나빠지고 위험도가 높아진다.

긴 생명 주기

전역 변수 생명주기는 어플리케이션의 생명주기와 같다.

  • 메모리 소요시간이 길다.
  • 상태를 변경할 수 있는 기간이 길어진다.

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

전역 변수의 검색 속도가 가장 느리다.

네임스페이스 오염

자바스크립트는 파일이 분리되어 있다고 하더라도 하나의 전역 스코프를 공유한다. 따라서 전역 변수나 전역 함수가 중복될 수 있다.


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

즉시 실행 함수

모든 코드를 즉시 실행 함수로 감싸면 모든 변수는 지역 변수가 된다. 라이브러리에서 많이 사용된다.

네임스페이스 객체

전역에 하나의 객체를 생성하고 이를 네임스페이스 역할을 하게 합니다. 그리고 전역 변수를 사용하고 싶은 변수를 프로퍼티로 추가합니다. 이는 식별자 충돌을 방지해주긴 하지만 네임스페이스 객체 자체가 전역변수이기 때문에 주의해야 한다.

var MYAPP = {};
MYAPP.name = 'Lee';

모듈 패턴

변수들과 매소들들을 담아 = 캡슐화 = 정보 은닉: 즉시 실행 안에서 동작하는 얘들은 사실상 private, return 하는 얘들만 public으로 동작) = 클래스와 비슷

ES6모듈

브라우저에서 사용할 수 있음
타입을 모듈로 지정
권장되는건 확장가가 .mjs(moduleJS)
internet explore에는 안됨
transfiling 이나 bundling을 해줘야 하기 때문에 아직 까지는 webpack 같은 모듈러를 많이 사용...!


Webpack 모듈 번들링

번들링 시정

  • 개발 시점
  • 빌드 시점
<script type='moudle' src=lib.mjs' />

을 안해줘도 되는 이유

webpack에서 모듈 번들링을 통해 모듈 번들링을 해서 1개 또는 n개의 번들들이 만들어지고 html에서 script를 만다면 번들이 실행된다.

  • 개발시점 : 코드 변경하고 저장하면 번들링이 바로 실행(새로고침 안해도됨)
  • 빌드시점 : 배포전 번들링을 함(최적화, 코드 스플리팅, 트리 쉐이킹 등등)

최적화 : 크기 작게
스플리팅 : 나눠서 들어갓을떄만 실행
쉐이킹 : 사용하지 않는 얘들 날려서 번들에 포함 안되게 해줌

0개의 댓글