Wednesday, January 23, 2019

JavaScript private fields

There is no private keyword in ES5 and ES6, so to create a private field we need to make up a workaround
  
function MyObj(val){
   let _val = val;
  
   return{
      getVal: function() { return _val; },
      setVal: function(newVal) { _val = newVal; }
  };
}

The MyObj(..) function is a factory that returns a new object every time we call it, so no necessary to use a new keyword. The object has 2 methods - getter and setter so that we can manipulate with the _val value
  
var o = MyObj(5);
console.log(o.getVal()); //5
o.setVal(8);
console.log(o.getVal()); //8

As long as _val is declared with the let keyword, it's impossible to access it directly from a different context
  
o._val = 10;
console.log(o.getVal()); //_val is still 8

o._val = 10 creates a completely separate property _val inside the object o, you can update it independently from our private field.

If for some reason you cannot use ES6, there is another solution:
  
var F = (function C(a){
  var a;
  var getSecretMessage = function(){
   return 'A secret messages';
  };
    
  var innerF = function(){
    return {
      A: function(_a){
        if (_a){
          if (_a >= 0 && _a <= 100){
         a = _a;
          }
        }
        return a;
      },
      getMessage: function(){
       return getSecretMessage() + ': ' + a;
      }
    };
  };
  
  return innerF;
})();

Try it in fiddler: https://jsfiddle.net/AndrewBuntsev/o3m12uzc/
The approach above utilizes closure concept, so to understand the code it is necessary to get familiar with the concept first.
In two words, every function in JS can have its own closure - extra storage for additional data. That storage is completely private, i.e. not accessible from other functions. To inspect the storage use developer tools. For the example above the closure is the following. There is a special section 'Closure' - to see it use console.dir(F) call.

No comments:

Post a Comment