네임스페이스
는 개체를 구분할 수 있는 범위를 나타내는 말이다.
좀 더 풀어 말하자면, 프로그래밍 언어에서 특정한 엔티티(Entity: 저장되고, 관리되어야 하는 데이터의 집합.)를 이름에 따라 구분할 수 있는 범위를 말하는 것이다. 즉, 일반적으로 하나의 namespace에서는 하나의 이름이 단 하나의 개체만을 가리키게 된다.
이를 쉽게 예를 들어 보겠다.
이 때 컴퓨터는 A의 소속이 어디인지를 본다. 이 A는 a폴더, 이 A는 b폴더.
이처럼, 파일 시스템(디렉토리)은 파일에 이름을 할당하는 이름공간이며 컴퓨터는 이를 기준으로 파일을 구별한다. 네임스페이스는 일종의 소속
이라고 생각해도 괜찮다.
이름 충돌
이다.네임스페이스는 코드에서 이름이 서로 충돌하는 문제를 해결하기 위해 나온 개념이다.
자바스크립트 엔진은 함수의 이름(여기서는 foo)만을 보고 어느 함수를 가리키는지 알 수 없다. 그렇다면 함수 이름을 변경해야 할까? 그러나,
이 때, 네임스페이스는 이러한 문맥을 구분해주는 역할을 한다. foo()가 내가 내 코드 내에서 정의한 함수인지, 외부 라이브러리에서 정의된 함수인지 자바스크립트 엔진에게 힌트를 준다. 이제 다시 첫 문장을 읽어보면 얼추 이해가 갈 것이다.
네임스페이스는 개체를 구분할 수 있는 범위이다.
식별자는 어떤 값을 구별할 수 있어야 하므로 유일(unique)해야 하고, 결국 식별자는 중복될 수 없다. 하나의 값은 유일한 식별자에 연결(name binding)되어야 한다. 이 때 스코프(scope, 유효 범위)의 개념을 적용하면 같은 이름의 식별자라도 각각 다른 스코프에서 사용이 가능해진다. 이것 또한 자바스크립트에서의 네임스페이스의 개념이다.
자바스크립트에서 네임스페이스의 개념을 사용하는 가장 큰 이유는 전역변수 억제
이다. 자바스크립트는 C++, C#, JAVA 등의 다른 언어들과는 달리 명시적인 키워드로 네임스페이스를 사용하지 않으며, 자바스크립트의 여러 특성을 사용하여 구현한다.
방금 말했듯이,
자바스크립트에서 네임스페이스를 사용하는 가장 큰 목적은
전역변수 억제
이다.
전역변수 사용을 남발하게 되면 다음과 같은 여러 문제점들이 생긴다.
위와 같은 이유들로, 전역 변수를 반드시 사용해야 할 이유를 찾지 못한 경우 지역 변수를 사용하는 것이 좋다.
변수의 스코프(유효 범위)는 좁을수록 좋다
전역변수의 사용을 억제하는 방법은 여러가지가 있다.
네임스페이스
역할을 담당할 객체
를 생성하고전역 변수
처럼 사용하고 싶은 변수를 프로퍼티
로 추가한다.// 네임스페이스 사용하기
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 서적