네임스페이스
는 개체를 구분할 수 있는 범위를 나타내는 말이다.
좀 더 풀어 말하자면, 프로그래밍 언어에서 특정한 엔티티(Entity: 저장되고, 관리되어야 하는 데이터의 집합.)를 이름에 따라 구분할 수 있는 범위를 말하는 것이다. 즉, 일반적으로 하나의 namespace에서는 하나의 이름이 단 하나의 개체만을 가리키게 된다.
이를 쉽게 예를 들어 보겠다.
- a라는 폴더와 b라는 폴더에 A라는 파일이 있다.
- 컴퓨터 입장에서는 두 폴더 각각의 A를 파일명으로 구분하지 못한다. 이름이 같기 때문이다.
이 때 컴퓨터는 A의 소속이 어디인지를 본다. 이 A는 a폴더, 이 A는 b폴더.
이처럼, 파일 시스템(디렉토리)은 파일에 이름을 할당하는 이름공간이며 컴퓨터는 이를 기준으로 파일을 구별한다. 네임스페이스는 일종의 소속
이라고 생각해도 괜찮다.
네임스페이스의 필요성
- foo() 함수를 정의해서 코드를 작성했다.
- 라이브러리의 필요성을 느끼고 외부 라이브러리를 추가했다.
이 때, 외부 라이브러리에도 동일한 이름의 foo() 함수가 있을 수 있다. 이는 곧이름 충돌
이다.
네임스페이스는 코드에서 이름이 서로 충돌하는 문제를 해결하기 위해 나온 개념이다.
자바스크립트 엔진은 함수의 이름(여기서는 foo)만을 보고 어느 함수를 가리키는지 알 수 없다. 그렇다면 함수 이름을 변경해야 할까? 그러나,
- 외부 라이브러리에 정의된 함수의 이름은 바꿀 수 없다.
- 내가 작성한 코드는 이미 완성본에 가까워졌으므로 코드 내 모든 함수명을 변경하는 것은 비효율적이다.
이 때, 네임스페이스는 이러한 문맥을 구분해주는 역할을 한다. foo()가 내가 내 코드 내에서 정의한 함수인지, 외부 라이브러리에서 정의된 함수인지 자바스크립트 엔진에게 힌트를 준다. 이제 다시 첫 문장을 읽어보면 얼추 이해가 갈 것이다.
네임스페이스는 개체를 구분할 수 있는 범위이다.
식별자는 어떤 값을 구별할 수 있어야 하므로 유일(unique)해야 하고, 결국 식별자는 중복될 수 없다. 하나의 값은 유일한 식별자에 연결(name binding)되어야 한다. 이 때 스코프(scope, 유효 범위)의 개념을 적용하면 같은 이름의 식별자라도 각각 다른 스코프에서 사용이 가능해진다. 이것 또한 자바스크립트에서의 네임스페이스의 개념이다.
자바스크립트의 네임스페이스
자바스크립트에서 네임스페이스의 개념을 사용하는 가장 큰 이유는 전역변수 억제
이다. 자바스크립트는 C++, C#, JAVA 등의 다른 언어들과는 달리 명시적인 키워드로 네임스페이스를 사용하지 않으며, 자바스크립트의 여러 특성을 사용하여 구현한다.
전역변수 억제의 필요성
방금 말했듯이,
자바스크립트에서 네임스페이스를 사용하는 가장 큰 목적은 전역변수 억제이다.
전역변수 사용을 남발하게 되면 다음과 같은 여러 문제점들이 생긴다.
- 암묵적 결합
전역 변수는 모든 코드가 참조하고 변경할 수 있는 암묵적 결합(implicit coupling)을 허용하기 때문에 코드의 가독성이 나빠지고 의도치 않게 상태가 변경될 수 있는 위험성도 높아진다. - 긴 생명 주기
전역 변수는 생명 주기가 길어 메모리 리소스를 오랜 기간 동안 소비하므로 전역 변수의 상태를 변경할 수 있는 시간도, 기회도 많다. 게다가 var 키워드는 변수의 중복 선언까지 허용하기 때문에 실수로 중복된 이름의 변수를 선언하면 의도치 않게 재할당이 이뤄질 위험이 있다. - 스코프 체인 상에서 중점에 존재
전역 객체는 스코프 체인 상에서 가장 상위 요소이다. 즉 변수를 검색할 때 전역 변수가 가장 마지막에 검색되며, 전역 변수의 검색 속도가 제일 느리다. 물론 미미한 차이지만, 속도차는 분명히 존재한다.
네임스페이스는 전역변수의 사용을 억제한다
위와 같은 이유들로, 전역 변수를 반드시 사용해야 할 이유를 찾지 못한 경우 지역 변수를 사용하는 것이 좋다.
변수의 스코프(유효 범위)는 좁을수록 좋다
전역변수의 사용을 억제하는 방법은 여러가지가 있다.
- 즉시 실행 함수
- 네임스페이스
- 모듈 패턴
- 모듈화 (ES6 도입)
네임스페이스로 전역변수의 사용 억제하기
- 전역의
네임스페이스
역할을 담당할객체
를 생성하고 전역 변수
처럼 사용하고 싶은 변수를프로퍼티
로 추가한다.
// 네임스페이스 사용하기
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 서적
'코딩' 카테고리의 다른 글
[자바스크립트] 값과 표현식, 문 (0) | 2022.05.23 |
---|---|
[자바스크립트] 변수(var, let, const)와 변수 호이스팅 (0) | 2022.05.23 |