2019년 10월 12일

전역 객체

전역 객체를 사용하면 어디서나 사용 가능한 변수나 함수를 만들 수 있습니다. 전역 객체는 언어 자체나 호스트 환경에 기본 내장되어 있는 경우가 많습니다.

브라우저 환경에선 전역 객체를 window, Node.js 환경에선 global라고 부르는데, 각 호스트 환경마다 부르는 이름은 다릅니다.

전역 객체의 이름을 globalThis로 표준화하자는 내용이 최근에 자바스크립트 명세에 추가되었기 때문에 모든 호스트 환경이 이를 따라야 하죠. Chromium 기반이 아닌 몇몇 브라우저는 아직 globalThis를 지원하진 않지만, 이에 대한 폴리필(polyfill)을 쉽게 만들 수 있습니다.

본 튜토리얼은 브라우저 환경에서 구동되기 때문에 window라는 전역 객체를 사용하도록 하겠습니다. 다른 호스트 환경에서 작업하고 계신다면 window대신 globalThis를 사용하시면 됩니다.

전역 객체의 모든 프로퍼티는 아래와 같이 직접 접근할 수 있습니다.

alert("Hello");
// 위와 동일하게 동작합니다.
window.alert("Hello");

브라우저에서 let이나 const가 아닌 var로 선언한 전역 함수나 전역 변수는 전역 객체의 프로퍼티가 됩니다.

var gVar = 5;

alert(window.gVar); // 5 (var로 선언한 변수는 전역 객체 window의 프로퍼티가 됩니다)

하위 호환성 때문에 이런 방식으로 전역 객체를 사용해도 동작은 하지만, 이 방법은 쓰지 않으시길 바랍니다. 모듈을 사용하는 모던 자바스크립트는 이런 방식을 지원하지 않습니다.

var 대신 let을 사용하면 위 예시와는 달리 전역 객체를 통해 변수에 접근할 수 없습니다.

let gLet = 5;

alert(window.gLet); // undefined (let으로 선언한 변수는 전역 객체의 프로퍼티가 되지 않습니다.)

중요한 변수라서 모든 곳에서 사용할 수 있게 하려면, 아래와 같이 전역 객체에 직접 프로퍼티를 추가해 주시기 바랍니다.

// 모든 스크립트에서 현재 사용자(current user)에 접근할 수 있게 이를 전역 객체에 추가함
window.currentUser = {
  name: "John"
};

// 아래와 같은 방법으로 모든 스크립트에서 currentUser에 접근할 수 있음
alert(currentUser.name);  // John

// 지역 변수 'currentUser'가 있다면
// 지역 변수와 충돌 없이 전역 객체 window에서 이를 명시적으로 가져올 수 있음
alert(window.currentUser.name); // John

전역 변수는 되도록 사용하지 않는 것이 좋습니다. 함수를 만들 땐 외부 변수나 전역 변수를 사용하는 것보다 ‘인풋’ 변수를 받고 이를 이용해 '아웃풋’을 만들어내게 해야 테스트도 쉽고, 에러도 덜 만들어냅니다.

폴리필 사용하기

전역 객체를 이용해 현재 사용중인 브라우저가 최신 자바스크립트 기능을 지원하는지 여부를 확인할 수 있습니다.

내장 객체 Promise를 지원하는지 여부를 아래와 같이 테스트할 수 있죠. 구식 브라우저는 Promise 객체를 지원하지 않기 때문에 alert 창이 뜰 겁니다.

if (!window.Promise) {
  alert("구식 브라우저를 사용 중이시군요!");
}

명세에는 있는 기능이지만 해당 기능을 지원하지 않는 오래된 브라우저를 사용하고 있다면 직접 함수를 만들어 전역 객체에 추가하는 방식으로 "폴리필"을 만들 수 있습니다.

if (!window.Promise) {
  window.Promise = ... // 모던 자바스크립트에서 지원하는 기능을 직접 구현함
}

요약

  • 전역 객체를 사용하면 어디서든 접근 가능한 변수를 만들 수 있습니다.

    전역 객체엔 Array와 같은 내장 객체, window.innerHeight(뷰포트의 높이를 반환함)같은 브라우저 환경 전용 변수 등이 저장되어 있습니다.

  • 전역 객체는 globalThis라는 보편적인 이름으로 불립니다.

    하지만 '관습’에 따라 브라우저에서는 window, Node.js에서는 global이라는 이름으로 불릴 때가 많습니다. globalThis는 제안 목록에 추가 된 지 얼마 안 된 기능이기 때문에, 비 크로미움 기반 브라우저에선 지원하지 않습니다(폴리필을 구현하면 사용할 수 있습니다).

  • 프로젝트 전체에서 꼭 필요한 변수만 전역 객체에 저장하도록 하고, 전역 변수는 가능한 한 최소한으로 사용합시다.

  • 모듈을 사용하고 있지 않다면, 브라우저에서 var로 선언한 전역 변수는 전역 객체의 프로퍼티가 됩니다.

  • 이해하기 쉽고 요구사항 변경에 쉽게 대응할 수 있는 코드를 구현하려면, window.x처럼 전역 객체의 프로퍼티에 직접 접근합시다.

튜토리얼 지도

댓글

댓글을 달기 전에 마우스를 올렸을 때 나타나는 글을 먼저 읽어주세요.
  • 추가 코멘트, 질문 및 답변을 자유롭게 남겨주세요. 개선해야 할 것이 있다면 댓글 대신 이슈를 만들어주세요.
  • 잘 이해되지 않는 부분은 구체적으로 언급해주세요.
  • 댓글에 한 줄짜리 코드를 삽입하고 싶다면 <code> 태그를, 여러 줄로 구성된 코드를 삽입하고 싶다면 <pre> 태그를 이용하세요. 10줄 이상의 코드는 plnkr, JSBin, codepen 등의 샌드박스를 사용하세요.