Last Updated: September 09, 2019
·
9.993K
· avgp

Protected properties in Javascript

ES 5 introduced a few really cool things regarding objects

One thing, that many people tell me is "Javascript is cool and stuff, but you can't have private or protected properties on objects, right?".
That's the point where you like me standing far away from any sharp objects.

As some of you may know, private properties are simple, if you follow the module pattern in Javascript:

var Cat = {};
Cat.create = function (config) {
  var that = config || {name: "Kitty"};
  var sound = "Meow";

  that.says = function() { return sound; };
  return that;
};

var myCat = Cat.create();
console.log(myCat.name + ": " + myCat.says()); // "Meow"
myCat.sound = "nyan";
console.log(myCat.name + ": " + myCat.says()); // still "Meow"

So in this example, we have a private property "sound" and you have to use the getter to access it.

But what about protected properties? The big issue with the approach here is that we can't really take advantage of passing in the "sound" property using config, without losing the tamper-proofness. Sure, there are work arounds (e.g. specifying additional parameters, etc.) - but there is a more elegant way:

ES5 comes in handy here with the lovely Object.defineProperty that allows us to add a property to an object with specified characteristics, such as being read-only.

So an extended version may look like this:

var Cat = {};
Cat.create = function (config) {
  var that = config || {name: "Kitty"};

  Object.defineProperty(that, "sound", {
    value: (config && config.sound) || "Meow", 
    writable: false 
  });

  that.says = function() { return this.sound; };
  return that;
};

var myCat = Cat.create();
alert(myCat.name + ": " + myCat.says()); // "Meow"
myCat.sound = "nyan";
alert(myCat.name + ": " + myCat.says()); // still "Meow"

var nyanCat = Cat.create({name: "Nyan Cat", sound: "Nyan"});
alert(nyanCat.name + ": " + nyanCat.says()); // "Nyan"
nyanCat.sound = "Mew";
alert(nyanCat.name + ": " + nyanCat.says()); // still "Nyan"

Funky, isn't it?

With this, we can easily hand in attributes that we don't want to give write-access to the public, but be abled to adjust them from within the class we're in.

As inheritance can be handled through the "config" parameter as well, you have something like protected variables (despite the fact, that they're still visible to the public).

1 Response
Add your response

Take a look at this fiddle - http://jsfiddle.net/aljey/n87t9/1/ (also available on google code - https://code.google.com/p/aljs/). The thing is, everything is possible with javascript, even complete access modifiers (public, protected, private).

over 1 year ago ·