본문 바로가기
프로그래밍/자바스크립트 ES6

자바스크립트 ES6 #14 전역 변수의 문제점

by 참외롭다 2023. 9. 18.
반응형

#전역변수 #지역변수 #전역객체 #즉시실햄함수 #모듈패턴 #네임스페이스객체


 

전역변수를 반드시 사용해야할 이유가 없다면 지역변수를 사용해야한다.

 

변수의 생명주기

 

변수는 자신이 선언된 위치에서 생성되고 소멸된다.

 

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

 

- 함수내부에서 선언된 지역변수함수호출되면 생성되고 종료되면 소멸된다.

 

function foo() {
  var x = "local";
  console.log(x);
  return x;
}
foo();
x; // x is not defined

 

전역에 선언된 변수런타임 이전엔진에 의해 초기화 된다.

 

함수 내부변수 선언함수호출직후 함수 내부 코드가 한 줄씩 실행 되기 이전에 엔진에 의해 먼저 실행된다.

 

이후, 몸체 내부 코드실행하면서 변수할당한다.

 

함수종료되면 변수소멸된다.

 

즉 지역변수의 생명주기는 함수의 생명주기와 일치한다.

 

지역 변수가 함수보다 오래 생존하는 경우도 있다.

 

변수의 생명주기는 메모리 공간이 확보된 시점부터 해제되어 가용 메모리풀반환되는 시점을 의미한다.

 

함수 내부에 선언된 변수함수생성스코프(렉시컬 환경)에 등록된다.

 

따라서 지역변수지역스코프가 존재할때 까지 유효하다. 스코프는 그 누구도 참조하지 않을때 가지비콜렉터에 의해 가용메모리풀반환된다.

 

함수종료되어도 누군가 함수의 스코프참조하고 있다면 스코프는 소멸되지않는다.(클로져)

 

호이스팅스코프 단위로 동작한다.

 

호이스팅은 변수 선언이 스코프선두로 끌어 올려진 것처럼 동작하는 자바스크립트 고유의 특징을 말한다.

var x = "global";

function foo() {
  // 함수내부의 코드를 실행하기전에 엔진은 변수 x를 선언하고 undefined로 초기화한다.(변수의 호이스팅)
  console.log(x); //undefined
  // 코드를 실행하며 변수 x에 문자열을 할당한다.
  var x = "local";
}

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

 

전역변수의 생명주기

 

전역객체는 코드가 실행되기전 엔진에 의해 어떤 것들 보다 빠르게 생성되는 특수한 객체이다.

 

- var 키워드로 선언한 전역 변수전역 객체프로퍼티가 된다.

 

- 전역변수생명주기전역객체생명주기와 일치한다.

 

- 브라우징 환경에서 전역객체window 이다.

 

- window 객체는 브라우져를 닫는 순간까지 유효하다.

 

- 전역변수전역객체프로퍼티이므로 전역변수는 브라우저를 닫는 순간까지 유효하다.

 


 

전역 변수의 문제점

 

암묵적 결합

 

전역변수의 선언은 어디서든 사용할 수 있는 변수를 사용하겠다는 의미이다.

 

- 전역변수의 사용은 모든 코드가 전역 변수를 참조하고 변경할 수 있는 암묵적 결합을 허용하는 것이다.

 

- 변수의 유효범위가 클수록 코드의 가독성은 나빠지고 의도치않은 변경이 발생할 수 있다.

 

긴 생명 주기

 

전역변수는 생명주기가 길다.

 

- 리소스를 오랜 기간 소비한다.

 

- 의도치않은 재할당이 이뤄질 가능성이 높아진다.

 

스코프 체인상 종점에 존재

 

변수를 검색할때 가장 마지막에 검색된다.

 

네임스페이스 오염

 

자바스크립트는 파일이 분리되어있더라도 하나전역스코프를 공유한다.

 

개발 중 다른 파일에 존재하는 동일한 이름의 전역 변수나 전역 함수가 전역 스코프 내에 존재할 경우 예상치못한 부작용이 발생한다.

 


 

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

 

즉시실행함수

 

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

 

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

 

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

foo; // foo is not defined

 

네임스페이스 객체

 

전역에 네임스페이스를 담당할 전역객체를 생성하고 전역 변수처럼 사용하려는 변수를 프로퍼티로 추가하는 방식이다.

 

var MYAPP = {};
MYAPP.name = "Lee";
MYAPP.name; //Lee

 

모듈패턴

 

관련있는 변수와 함수를 모아 즉시 실행함수로 감싸 하나의 모듈을 만든다.

 

- 모듈 패턴은 클로저를 기반으로 작동한다.

 

- 전역변수 억제는 물론 캡슐화 까지 구현할 수 있다.

 

- 캡슐화는 객체의 상태를 나타내는 프로퍼티와 프로퍼티를 참조하고 조작할 수 있는 동작인 메서드를 하나로 묶는 것을 말한다.

 

- 한정적인 정보의 은닉을 구현할 수 있다

 

- 반환되는 객체의 프로퍼티는 퍼블릭 맴버이고 몸체에 선언된 지역변수는 프라이빗 멤버이다

var Counter = (function () {
  var num = 0;
  return {
    increase() {
      // 상위 스코프인 익명 함수 내부에 선언된 변수인 num을 스코프 체인에 저장하고있다.
      return num++;
    },
    decrease() {
      // 상위 스코프인 익명 함수 내부에 선언된 변수인 num을 스코프 체인에 저장하고있다.
      return --num;
    },
  };
})();

Counter.num; // undefined
Counter.increase();
Counter.decrease();

 

ES6 모듈

 

파일 자체의 독자적인 모듈 스코프를 제공한다.

 

 

#전역변수 #지역변수 #전역객체 #즉시실햄함수 #모듈패턴 #네임스페이스객체

반응형