General setter/getter methods for private properties

design-patterns, javascript

Solution

I think you should be looking at ES5 getters and setters. These allow you to create things that look like properties, but really call functions behind them. For example:

var _a : 'nuthin',
var obj = {
  get a: function() { return this._a; },
  set a: function(a) { this._a = a; }
}

obj.a = 'sumpin';
console.log(obj.a); // nuthin

You can also create getters and setters inside of a constructor, but the syntax is clunkier. Like this:

function nooObject(){
  var _a = 'nuthin';
  Object.defineProperties(this, {
    "a": { get: function () { return _a; } 
           set: function(a) { this._a = a; } }
  });
}

There are many more things you can do with `Object.defineProperties`. Read all about it on MDN

Problem

I can create private members on a JavaScript class like this: ``` function Class(_foo, _bar) { var foo = _foo, // private, yay bar = _bar; // also private, also yay } ``` How can I implement general setter/getter methods for this class? I suppose one way to do it would be to use `eval`: ``` function Class(_foo, _bar) { var foo = _foo, bar = _bar; this.get = function(property) { return eval(property); }; this.set = function(property, value) { eval(property + " = " + value); }; } ``` However, this solution is ugly. Another way to do it is to create a `private` object and then access properties on that: ``` function Class(foo, bar) { var private = { foo: foo, bar: bar }; this.get = function(property) { return private[property]; }; this.set = function(property, value) { private[property] = value; }; } ``` I don't like this solution very much either, though, because it means I have to access the `private` object all over the place. Surely there's a cleaner way to provide a general getter/setter for private properties on a JavaScript class? I realize similar questions have already been asked, but it doesn't appear that any of them ask this specific question; that is, how to provide a single getter/setter for all of the private properties on the class. Here's a jsFiddle with the two examples.

Original source