[JS] 전역 변수의 문제점

vSsongv·2021년 11월 26일
0

JS

목록 보기
12/40
post-thumbnail
  • 전역 변수는 값이 변경될 위험이 있기 때문에 전역 변수를 반드시 사용해야 할 이유가 없다면 지역 변수를 사용해야 한다.

✅ 변수의 생명 주기

🔰 지역 변수의 생명 주기

  • 변수는 생성되고 소멸되는 생명 주기가 있다. 생명 주기가 없다면 한번 선언된 변수는 프로그램을 종료하지 않는 한 영원히 메모리 공간을 영원히 점유하게 된다.
  • 변수는 자신이 선언된 위치에서 생성되고 소멸한다.
  • 전역 변수의 생명 주기는 애플리케이션의 생명 주기와 같다.
  • 지역 변수는 함수가 호출되면 생성되고 함수가 종료하면 소멸한다.
	function foo () {
	  var x = local;
	  console.log(x);
      return x;
    }
	foo();
	console.log(x); //ReferenceError x is not defined
  • 지역변수 x는 foo 함수가 호출되기 전까지는 생성되지 않는다. foo함수를 호출하지 않으면 함수 내부의 변수 선언문이 실행되지 않기 때문.
  • foo 함수를 호출하면 함수 몸체의 다른 문들 중 선언문이 제일 먼저 실행된다.
  • 함수가 종료되면 x변수도 소멸되어 생몀 주기가 종료된다.
  • 따라서 지역변수의 생명 주기는 함수의 생명 주기와 일치한다.

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

  • 따라서 변수는 자신이 등록된 스코프가 소멸될때까지 유효하다. -> 할당된 메모리 공간은 그 누구도 참조하지 않을 때 가비지 콜렉터에 의해 해제되어 가용 메모리 풀에 반환된다.
	var x =  'global';
	function foo () {
	  console.log(x); //undefined. 함수 내부에서 아직 할당되지 않았기 때문.
      	  var x = 'local';
    }
	foo();
	console.log(x); //global
  • 호이스팅은 스코프를 단위로 동작한다.
  • 지역 변수는 함수 내부에서 유효하다.

🔰 전역 변수의 생명 주기

  • 전역 코드는 마지막 문이 실행되어 더 이상 실행할 문이 없을 때 종료한다.

    ❓ 전역 객체

    • 전역 객체는 코드가 실행되기 이전 단계에 어떤 객체보다도 먼저 생성되는 특수한 객체이다.
  • var 키워드로 선언한 전역 변수의 생명 주기는 전역 객체의 생명 주기와 일치한다.

✅ 전역 변수의 문제점

💠 암묵적 결합

  • 모든 코드가 전역 변수를 참조하고 변경할 수 있는 것.
  • 변수의 유효 범위가 크면 클수록 코드의 가독성은 나빠지고 의도치 않게 상태가 변화할 수 있는 위험성도 높아진다.

💠 긴 생명 주기

  • 전역 변수는 생명 주기가 길다.
  • 즉 변수의 상태를 변경할 수 있는 시간도 길다.

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

  • 전역 변수는 스코프 체인 상에서 종점에 존재한다. -> 가장 마지막에 검색된다.
  • 즉 **전역 변수의 검색 속도가 가장 느리다.

💠 네임 스페이스 오염

  • JS는 파일이 분리되어 있더라도 하나의 전역 스코프를 공유한다. -> 파일이 분리되어 있더라도 파일 내부의 동등한 이름의 전역 변수나 전역 함수가 같은 스코프 내에 존재할 경우 예상치 못한 결과가 발생할 수도 있다.

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

변수의 스코프는 좁을수록 좋다.

🔰 즉시 실행 함수

  • 즉시 실행 함수는 단 한 번만 호출되므로, 모든 코드를 즉시 실행 함수로 감싸면 모든 변수는 즉시 실행 함수의 지역 변수가 된다.
  • 이 경우 전역 변수를 생성하지 않는다.-> 라이브러리에 주로 이용됨.
	(function () {
	  var foo = (); //즉시 실행 함수의 지역 변수
	
	console.log(foo);

🔰 네임스페이스 객체

  • 전역에 네임스페이스 역할을 담당할 객체를 선언하고, 전역 변수처럼 사용하고 싶은 변수를 프로퍼티로 추가하는 방법.

    ❓ 네임 스페이스

    • 구분이 가능하도록 정해놓은 범위나 영역
    • 전역 객체를 하나 만들고(단 하나만 만드는 것이 이상적이다) 모든 기능을 이 객체에 추가하는 패턴.
    • 같은 이름을 가진 변수들의 충돌을 방지하기 위해 이름이 존재하는 공간을 정의하는 기능을 함
	var MYAPP = {}; //전역 네임스페이스 객체
	
	MYAPP.name: 'Ssong';
	
	console.log(MYAPP.name); //Ssong
  • 네임스페이스 객체에 또 다른 네임스페이스 객체를 추가해서 계층적으로 구성할 수도 있다.
	var MYAPP = {};
	
	MYAPP.student = {
	  name: 'Lee',
	  gender: 'male'
	};
	
	console.log(MYAPP.student.name);

🔰 모듈 패턴

  • 클래스를 모방해서 관련이 있는 함수와 변수를 모아 즉시 실행 함수로 감싸서 모듈을 만드는 것.
  • 객체 지향 프로그래밍 언어는 public, private 등의 접근 제한자를 사용해 정보 은닉을 구현한다.
	var counter(function () {
	   //private 
	   var num = 0;
	   //외부로 공개할 데이터나 메소드를 프로퍼티로 추가한 후 객체를 반환한다.
	   return {
	     increase() {
	       return ++num;
	     }
	     decrese() {
	       return --num;
	     }
	   }
        }());

console.log(counter.num); //undefined -> private변수는 외부에 노출되지 않는다.
  • 한정적이기는 하지만 정보 은닉을 구현하기 위해 사용된다.

🔰 ES6 모듈

  • 이제는 모듈을 써라!
  • ES6모듈을 사용하면 전역 변수를 사용할 수 없다.
  • ES6모듈은 파일 자체에 독자적인 모듈 스코프를 제공한다.
  • 모듈 내에 var 키워드로 선언된 변수는 전역 변수가 아니다.
  • ES6 모듈은 IE같은 구형 브라우저에서는 동작하지 않는다.
  • script 태그에 type="module" 어트리뷰트를 추가하면 로드된 자바스크립트 파일은 모듈로서 동작한다. 모듈의 파일 확장자는 mjs를 권장한다.
<script type="module" src="lib.mjs"></script>
<script type="module" src="app.mjs"></script>
  • 모듈은 48장에서 자세히 살펴보자.

<모던 자바스크립트 deepdive와, 추가 탐구한 내용을 정리한 포스트입니다.>

profile
wanna be bright person✨ Front-End developer

0개의 댓글