https://www.sitepoint.com/javascript-private-class-fields/#static-methods-and-properties
class Animal {
  constructor(name = 'anonymous', legs = 4, noise = 'nothing') {
    this.type = 'animal';
    this.name = name;
    this.legs = legs;
    this.noise = noise;
  }
  speak() {
    console.log(`${this.name} says "${this.noise}"`);
  }
  walk() {
    console.log(`${this.name} walks on ${this.legs} legs`);
  }
}
- Setter는 값들을 정의하는 특별한 메소드
 - getter는 value를 리턴하는 데에만 사용하는 특별 메소드
 
class Animal {
  constructor(name = 'anonymous', legs = 4, noise = 'nothing') {
    this.type = 'animal';
    this.name = name;
    this.legs = legs;
    this.noise = noise;
  }
  speak() {
    console.log(`${this.name} says "${this.noise}"`);
  }
  walk() {
    console.log(`${this.name} walks on ${this.legs} legs`);
  }
  // setter
  set eats(food) {
    this.food = food;
  }
  // getter
  get dinner() {
    return `${this.name} eats ${this.food || 'nothing'} for dinner.`;
  }
}
let rex = new Animal('Rex', 4, 'woof');
rex.eats = 'anything';
console.log( rex.dinner );  // Rex eats anything for dinner.
method를 static 키워드와 함께 정의하면 instance를 생성하지 않아도 해당 method를 호출 할 수 있게 만든다.
아래 예시에서는
static get COUNT() {
    return Human.count;
  }
부분이다.
class Human extends Animal {
  constructor(name) {
    // call the Animal constructor
    super(name, 2, 'nothing of interest');
    this.type = 'human';
    // update count of Human objects
    Human.count++;
  }
  // override Animal.speak
  speak(to) {
    super.speak();
    if (to) console.log(`to ${to}`);
  }
  // return number of human objects
  static get COUNT() {
    return Human.count;
  }
}
// static property of the class itself - not its objects
Human.count = 0;
instance가 아니라 Human.COUNT 그 자체로 Human.count를 호출하고 있다.
console.log(`Humans defined: ${Human.COUNT}`); // Humans defined: 0
let don = new Human('Don');
console.log(`Humans defined: ${Human.COUNT}`); // Humans defined: 1
let kim = new Human('Kim');
console.log(`Humans defined: ${Human.COUNT}`); // Humans defined: 2
ES6의 Class의 모든 프로퍼티들은 기본적으로 public이다.
아래 예시를 보면 set에 의해 rex.food가 정의되어야 하지만, rex.food에 직접 접근하고 있는 것을 볼 수 있다.
class Animal {
  constructor(name = 'anonymous', legs = 4, noise = 'nothing') {
    this.type = 'animal';
    this.name = name;
    this.legs = legs;
    this.noise = noise;
  }
  set eats(food) {
    this.food = food;
  }
  get dinner() {
    return `${this.name} eats ${this.food || 'nothing'} for dinner.`;
  }
}
let rex = new Animal('Rex', 4, 'woof');
rex.eats = 'anything';      // standard setter
rex.food = 'tofu';          // bypass the eats setter altogether
console.log( rex.dinner );  // Rex eats tofu for dinner.
이를 ES6에서는 hash# prefix로 외부에서 접근을 막는다.
class MyClass {
  a = 1;          // .a is public
  #b = 2;         // .#b is private
  static #c = 3;  // .#c is private and static
  incB() {
    this.#b++;
  }
}
let m = new MyClass();
m.incB(); // runs OK
m.#b = 0; // error - private property cannot be modified outside class