Search code examples
javascriptmodulereferenceclosuresencapsulation

JavaScript closures for encapsulating data can be circumvented?


I always thought of JavaScript closures as a perfect way for encapsulating data, sort of making variables private. But I recently realized that this pattern is very easily broken by exploiting reference semantics:

function creator() {
  var x = {
    key: 3
  };
  return function() {
    return x;
  }
}

var instance = creator();

var y = instance();

y.key = 4;

//returns 4
//y is a refernce to x
console.log( instance() );

How do I make sure that the private part (variables defined in scope of creator() cannot be mutated from outside?


Solution

  • You should use getters and setters . Following MDN example you should be able to return the same value even if set differently:

    function creator() {
      var x = {
        get key() {
          return 4;
        },
        set key(x) {
          // do nothing
        }
      };
      return function() {
        return x;
      }
    }
    

    This way when you set key, the setter drops the input value and keeps the original init value.