자바스크립트 클래스 private 속성

자바스크립트는 ES6 이후부터 클래스(class) 문법이 도입되었습니다. 클래스를 사용하면 객체 지향 프로그래밍(OOP)의 여러 기능을 더 쉽게 활용할 수 있습니다. 하지만 기본적으로 자바스크립트의 클래스에는 접근 제한자(Private, Public, Protected) 개념이 없어서 클래스 속성에 직접 접근이 가능합니다.

하지만, 클래스의 속성들을 외부에서 접근할 수 없게 만들고 싶을 때가 있습니다. 이런 경우에는 자바스크립트에서 다양한 방법을 활용하여 Private 속성을 구현할 수 있습니다.

1. WeakMap을 이용한 Private 속성

ES6 이후의 자바스크립트에서는 WeakMap이라는 자료구조를 제공합니다. WeakMap은 키-값 쌍으로 데이터를 저장하며, 키는 객체만 허용되고 원시 타입은 허용되지 않습니다. 이 특성을 이용하여 클래스의 속성을 Private하게 만들 수 있습니다.

const privateProperty = new WeakMap();

class MyClass {
  constructor() {
    privateProperty.set(this, 'Private Value');
  }

  get privateProp() {
    return privateProperty.get(this);
  }

  set privateProp(value) {
    privateProperty.set(this, value);
  }
}

const myObj = new MyClass();
console.log(myObj.privateProp); // Output: Private Value
myObj.privateProp = 'New Private Value';
console.log(myObj.privateProp); // Output: New Private Value

위의 예제 코드에서는 WeakMap을 이용하여 privateProperty라는 WeakMap 객체를 생성합니다. 클래스의 속성을 WeakMap에 저장하고, getter와 setter 메서드로 외부에서 속성에 접근하도록 합니다. 이렇게 하면 외부에서는 privateProp을 통해서만 속성에 접근할 수 있고, WeakMap을 통해 속성이 실제로 저장되기 때문에 Private하게 유지할 수 있습니다.

2. 심볼(Symbol)을 이용한 Private 속성

ES6 이후의 자바스크립트에서는 심볼(Symbol)이라는 원시 타입을 제공합니다. 심볼은 유일한 토큰을 생성하여 속성을 외부로부터 감추는 데 사용할 수 있습니다. 이를 이용하여 클래스의 속성을 Private하게 만들 수 있습니다.

const privateProperty = Symbol('privateProperty');

class MyClass {
  constructor() {
    this[privateProperty] = 'Private Value';
  }

  get privateProp() {
    return this[privateProperty];
  }

  set privateProp(value) {
    this[privateProperty] = value;
  }
}

const myObj = new MyClass();
console.log(myObj.privateProp); // Output: Private Value
myObj.privateProp = 'New Private Value';
console.log(myObj.privateProp); // Output: New Private Value

위의 예제 코드에서는 심볼을 이용하여 privateProperty라는 심볼을 생성합니다. 클래스의 속성을 심볼을 키로 사용하여 선언하고, getter와 setter 메서드로 외부에서 속성에 접근하도록 합니다. 심볼은 고유한 값이므로 외부에서는 해당 심볼을 모르는 이상 속성에 접근할 수 없어 Private하게 유지됩니다.

3. 네이밍 컨벤션을 이용한 ‘의도적인’ Private 속성

자바스크립트에서는 네이밍 컨벤션을 이용하여 ‘의도적인’ Private 속성을 만들 수 있습니다. 단지 속성 이름에 언더스코어(_)를 추가하는 것만으로도 외부에서 접근하지 않는 것처럼 보이게 할 수 있습니다. 하지만 이 방법은 실제 Private하지는 않기 때문에 개발자의 인지하에 속성에 접근이 가능합니다.

class MyClass {
  constructor() {
    this._privateProperty = 'Private Value';
  }

  get privateProp() {
    return this._privateProperty;
  }

  set privateProp(value) {
    this._privateProperty = value;
  }
}

const myObj = new MyClass();
console.log(myObj.privateProp); // Output: Private Value
myObj.privateProp = 'New Private Value';
console.log(myObj.privateProp); // Output: New Private Value

위의 예제 코드에서는 _privateProperty라는 네이밍 컨벤션을 이용하여 ‘의도적인’ Private 속성을 만듭니다. 하지만 이 속성은 실제 Private하지 않고, 단지 개발자의 약속에 따라 속성에 접근하는 것을 제한할 뿐입니다.

결론

자바스크립트에는 클래스의 Private 속성을 지원하지 않지만, 다양한 방법을 통해 Private 속성을 구현할 수 있습니다. 이러한 방법들을 사용하면 객체의 정보 은닉과 캡슐화를 보다 효과적으로 구현할 수 있습니다. 개발자는 해당 클래스의 속성을 외부로부터 보호하여 의도하지 않은 접근에서 벗어나게 됩니다.