# 05. Private Data

Approaches for managing private data for ES6 classes:

1. Keeping private data in the environment of a class constructor
2. Marking private properties via a naming convention (e.g. a prefixed underscore)
3. Keeping private data in `WeakMaps`
4. Using symbols as keys for private properties

## Private data via constructor environments

```javascript
class Countdown {
  constructor(counter, action) {
    Object.assign(this, {
      dec() {
        if (counter < 1) return;
        counter--;
        if (counter === 0) {
          action();
        }
      }
    });
  }
}
```

## Private data via a naming convention

```javascript
class Countdown {
  constructor(counter, action) {
    this._counter = counter;
    this._action = action;
  }
  dec() {
    if (this._counter < 1) return;
    this._counter--;
    if (this._counter === 0) {
      this._action();
    }
  }
}
```

## Private data via `WeakMaps`

```javascript
const _counter = new WeakMap();
const _action = new WeakMap();

class Countdown {
  constructor(counter, action) {
    _counter.set(this, counter);
    _action.set(this, action);
  }
  dec() {
    let counter = _counter.get(this);
    if (counter < 1) return;
    counter--;
    _counter.set(this, counter);
    if (counter === 0) {
      _action.get(this)();
    }
  }
}
```

## Private data via symbols

```javascript
const _counter = Symbol("counter");
const _action = Symbol("action");

class Countdown {
  constructor(counter, action) {
    this[_counter] = counter;
    this[_action] = action;
  }
  dec() {
    if (this[_counter] < 1) return;
    this[_counter]--;
    if (this[_counter] === 0) {
      this[_action]();
    }
  }
}
```
