[자바스크립트] 네임스페이스(namespace)로 전역 변수 사용 억제하기

KangHyeYoon·2022년 5월 7일
1
post-thumbnail

네임스페이스개체를 구분할 수 있는 범위를 나타내는 말이다.

좀 더 풀어 말하자면, 프로그래밍 언어에서 특정한 엔티티(Entity: 저장되고, 관리되어야 하는 데이터의 집합.)를 이름에 따라 구분할 수 있는 범위를 말하는 것이다. 즉, 일반적으로 하나의 namespace에서는 하나의 이름이 단 하나의 개체만을 가리키게 된다.

이를 쉽게 예를 들어 보겠다.

  1. a라는 폴더와 b라는 폴더에 A라는 파일이 있다.
  2. 컴퓨터 입장에서는 두 폴더 각각의 A를 파일명으로 구분하지 못한다. 이름이 같기 때문이다.

이 때 컴퓨터는 A의 소속이 어디인지를 본다. 이 A는 a폴더, 이 A는 b폴더.
이처럼, 파일 시스템(디렉토리)은 파일에 이름을 할당하는 이름공간이며 컴퓨터는 이를 기준으로 파일을 구별한다. 네임스페이스는 일종의 소속이라고 생각해도 괜찮다.

네임스페이스의 필요성

  1. foo() 함수를 정의해서 코드를 작성했다.
  2. 라이브러리의 필요성을 느끼고 외부 라이브러리를 추가했다.
    이 때, 외부 라이브러리에도 동일한 이름의 foo() 함수가 있을 수 있다. 이는 곧 이름 충돌이다.

네임스페이스는 코드에서 이름이 서로 충돌하는 문제를 해결하기 위해 나온 개념이다.

자바스크립트 엔진은 함수의 이름(여기서는 foo)만을 보고 어느 함수를 가리키는지 알 수 없다. 그렇다면 함수 이름을 변경해야 할까? 그러나,

  • 외부 라이브러리에 정의된 함수의 이름은 바꿀 수 없다.
  • 내가 작성한 코드는 이미 완성본에 가까워졌으므로 코드 내 모든 함수명을 변경하는 것은 비효율적이다.

이 때, 네임스페이스는 이러한 문맥을 구분해주는 역할을 한다. foo()가 내가 내 코드 내에서 정의한 함수인지, 외부 라이브러리에서 정의된 함수인지 자바스크립트 엔진에게 힌트를 준다. 이제 다시 첫 문장을 읽어보면 얼추 이해가 갈 것이다.

네임스페이스는 개체를 구분할 수 있는 범위이다.

식별자는 어떤 값을 구별할 수 있어야 하므로 유일(unique)해야 하고, 결국 식별자는 중복될 수 없다. 하나의 값은 유일한 식별자에 연결(name binding)되어야 한다. 이 때 스코프(scope, 유효 범위)의 개념을 적용하면 같은 이름의 식별자라도 각각 다른 스코프에서 사용이 가능해진다. 이것 또한 자바스크립트에서의 네임스페이스의 개념이다.

자바스크립트의 네임스페이스

자바스크립트에서 네임스페이스의 개념을 사용하는 가장 큰 이유는 전역변수 억제이다. 자바스크립트는 C++, C#, JAVA 등의 다른 언어들과는 달리 명시적인 키워드로 네임스페이스를 사용하지 않으며, 자바스크립트의 여러 특성을 사용하여 구현한다.

전역변수 억제의 필요성

방금 말했듯이,

자바스크립트에서 네임스페이스를 사용하는 가장 큰 목적은 전역변수 억제이다.

전역변수 사용을 남발하게 되면 다음과 같은 여러 문제점들이 생긴다.

  • 암묵적 결합
    전역 변수는 모든 코드가 참조하고 변경할 수 있는 암묵적 결합(implicit coupling)을 허용하기 때문에 코드의 가독성이 나빠지고 의도치 않게 상태가 변경될 수 있는 위험성도 높아진다.
  • 긴 생명 주기
    전역 변수는 생명 주기가 길어 메모리 리소스를 오랜 기간 동안 소비하므로 전역 변수의 상태를 변경할 수 있는 시간도, 기회도 많다. 게다가 var 키워드는 변수의 중복 선언까지 허용하기 때문에 실수로 중복된 이름의 변수를 선언하면 의도치 않게 재할당이 이뤄질 위험이 있다.
  • 스코프 체인 상에서 중점에 존재
    전역 객체는 스코프 체인 상에서 가장 상위 요소이다. 즉 변수를 검색할 때 전역 변수가 가장 마지막에 검색되며, 전역 변수의 검색 속도가 제일 느리다. 물론 미미한 차이지만, 속도차는 분명히 존재한다.

네임스페이스는 전역변수의 사용을 억제한다

위와 같은 이유들로, 전역 변수를 반드시 사용해야 할 이유를 찾지 못한 경우 지역 변수를 사용하는 것이 좋다.

변수의 스코프(유효 범위)는 좁을수록 좋다

전역변수의 사용을 억제하는 방법은 여러가지가 있다.

  • 즉시 실행 함수
  • 네임스페이스
  • 모듈 패턴
  • 모듈화 (ES6 도입)

네임스페이스로 전역변수의 사용 억제하기

  1. 전역의 네임스페이스 역할을 담당할 객체를 생성하고
  2. 전역 변수처럼 사용하고 싶은 변수를 프로퍼티로 추가한다.
// 네임스페이스 사용하기

var MYAPP = {};

MYAPP.name = 'kang';

console.log(MYAPP.name);    // kang

// 계층적 네임스페이스 구성

var MYAPP = {};

MYAPP.person = {
    name: 'kang',
    age: 22,
};

console.log(MYAPP.person.name);     // kang

네임스페이스의 한계점

네임스페이스를 분리하면 식별자 충돌을 방지하는 효과는 있으나, 네임스페이스 객체 자체가 전역 변수에 할당되는 형식이기 때문에 한계를 피할 수 없다. 전역변수 사용을 억제하려고 사용한 개념인데 결국엔 전역 변수에 묶여버린 셈이다.

그래서 최근에는 모듈의 개념을 더 선호하고 있는 추세이다.
대부분의 객체지향 프로그래밍 언어는 클래스를 구성하는 멤버에 대해 public, private, protected 등의 접근 제한자(acces modifier)를 제공하여 원하지 않는 외부의 접근으로부터 내부를 보호하고 제한된 접근만을 제공한다. 그러나 자바스크립트는 접근 제한자를 제공하지 않으므로 한정적이지만 모듈 패턴을 통해 전역 네임스페이스의 오염을 막는다.

또한, ES6 모듈은 파일 자체의 독자적인 모듈 스코프를 제공하므로 보다 강력한 전역 변수 억제가 가능하다.

끝마치며

네임스페이스는 상당히 중요한 개념이므로, 직접적으로 사용할 기회가 적더라도 꼭 알아두어야 한다. 다른 언어에서도 가장 먼저 배우는 상식 중 하나이고, 프로그래밍 언어 동작에 상당한 영향을 미친다. 이후 전역변수 억제에 대한 자세한 글을 작성해보겠다.
참고 : 모던 자바스크립트 Deep Dive 서적

profile
사람 입장에서 생각하는 컴퓨터입니다.

0개의 댓글