2

I'm trying to understand why I need to use WeakMaps to create private class members, instead of just using a normal variable. They both create encapsulation with closures, and module imports.

(function encapsulation() {
  const my_var = 'My secret info';
  const my_var2 = new WeakMap();

  class Test {
    constructor() {
      my_var2.set(this, 'My secret info 2');
      console.log(my_var); // My secret info
      console.log(my_var2.get(this)); // My secret info 2
    }
  }

  const t = new Test();
})();


console.log(my_var); // undefined
console.log(my_var2); // undefined

// Same result!
123
  • 23
  • 2

1 Answers1

4

The problem with an ordinary variable like my_var is that it will only save data for a single instantiation of the class:

const Test = (function encapsulation() {
  let my_var = 'My secret info';

  class Test {
    constructor(param) {
      my_var = param;
    }
    getInfo() {
      return my_var;
    }
  }
  return Test;
})();

const t1 = new Test('foo');
const t2 = new Test('bar');
console.log(t1.getInfo());
// the above returns 'bar'... uh oh, but we passed in 'foo' to `t1`! Our data is lost!
console.log(t2.getInfo()); // 'bar'

Thus, the need for a WeakMap, to hold separate data for each instantiation:

const Test = (function encapsulation() {
  const my_var2 = new WeakMap();

  class Test {
    constructor(param) {
      my_var2.set(this, param);
    }
    getInfo() {
      return my_var2.get(this);
    }
  }
  return Test;
})();

const t1 = new Test('foo');
const t2 = new Test('bar');
console.log(t1.getInfo()); // 'foo', as expected
console.log(t2.getInfo()); // 'bar', as expected
CertainPerformance
  • 356,069
  • 52
  • 309
  • 320
  • That makes sense for proper encapsulation. So if i were using methods and properties that weren't mutated, going with a constant would be fine? – 123 May 28 '18 at 11:35
  • I'm not sure what mutation has to do with it - the problem is being able to access the data afterwards. Mutation is separate from reassignment. – CertainPerformance May 28 '18 at 11:39
  • Ah sorry, I suppose I meant to say if I only had one instance of the class ever. Having a constant would make sense then, as it wouldn't be re-asigned – 123 May 28 '18 at 11:50
  • You mean as one of the `my_var`s? Sure, but you wouldn't be able to pass private data *into* it, it would have to be hard-coded. – CertainPerformance May 28 '18 at 12:10