O'Reilly

Hiding Your Privates with JavaScript

By on  
JavaScript Privates

Believe it or not, there are a lot of people who strongly dislike JavaScript. For one reason or another, they simply can't stand the perceived lack of security and structure within the language. One of those perceived weaknesses is lack of the private designations for variables within structures. They have a point; if you stick a property on an object, or create d global variables, it's fair game for anyone. There is, however, a few very simple patterns you can use within JavaScript to keep access to a given object or variable private!

With "Classes"

You probably know that true classes don't exist in JavaScript, but using Function and prototypes we can simulate them pretty damn well. Using this pattern, you can also simulate private variables:

function MyClass(parameter) {
	
	// Create the private var
	var privateVar = 8,
		self = this;
	self.parameter = parameter
	
	// Function that handles the private
	function handlePrivate() {
		return privateVar ? privateVar-- :  false;
	}
	
	// Public method that calls the handler
	// Returns parameter until it's been accessed 8 times
	this.getPrivate() {
		return handlePrivate() ? self.parameter : null;
	}

}

Privates are made within the constructor and only the constructor. Adding privileged methods within the constructor give access to privates. In the sample above, the value is accessible only by the privileged method.

With Closures

The pattern centers around a closure with a scoped variable, returning an object or function with access to the variable. Here's a simple example:

var accessor = (function() {
	// Create the private var
	var privateVar = "You Can't See Me, ";
	
	// Some other functionality here that periodically changes privateVar, because it has access to it
	// [ more code here ]
	
	// Return the accessor
	return function(name) {
		return privateVar + name;
	};
})();

// Use!
// currentValue = accessor("David");  "You Can't See Me, David"

The privateVar variable is not available out side the closure so there's no way to access it directly. We do, however, have a define function with access to the variable and return that from the closure. Thus, the variable stays private, you can access its value, but no direct access is allowed. You could also return an object with methods for modifying the protected variable:

var accessor = (function() {
	
	// The "private"
	var val = 9;
	
	// An object for getting and setting
	return {
		get: function() {
			return val * 3;
		},
		set: function(s) {
			val = s;
		}
	};
})();

Of course, with the pattern above, a user could reassign the get method with something like:

accessor = function(n) { return "My custom string, " + n; }

..so be aware of that. Usually any functionality that handles private information stays within the closure, preventing issues with users overriding methods. Something like this:

var accessor = (function() {
	
	var permissions = {};
	
	function handleResult(perm) {
		// Do something with the result
	}
	
	return function(permissionToCheck, callback) {
		if(permissions[permissionToCheck]) != undefined) {
			callback(permissions[permissionToCheck]);
		}
		else {
			$.post({
				url: "/permissions"
				data: {
					perm: permissionToCheck
				}
			}).success(function(res) {
				callback(handleResult(res));
			});
		}
	};
	
})();

There's a certain beauty in the simplicity of JavaScript; don't write it off because it doesn't provide the same explicit structures as other languages!

O'Reilly Velocity Conference
Save 20% with discount code AFF20

Recent Features

  • Creating Scrolling Parallax Effects with CSS

    Introduction For quite a long time now websites with the so called "parallax" effect have been really popular. In case you have not heard of this effect, it basically includes different layers of images that are moving in different directions or with different speed. This leads to a...

  • An Interview with Eric Meyer

    Your early CSS books were instrumental in pushing my love for front end technologies. What was it about CSS that you fell in love with and drove you to write about it? At first blush, it was the simplicity of it as compared to the table-and-spacer...

Incredible Demos

  • MooTools Fun with Fx.Shake

    Adding movement to your website is a great way to attract attention to specific elements that you want users to notice. Of course you could use Flash or an animated GIF to achieve the movement effect but graphics can be difficult to maintain. Enter...

  • HTML5 Datalist

    One of the most used JavaScript widgets over the past decade has been the text box autocomplete widget.  Every JavaScript framework has their own autocomplete widget and many of them have become quite advanced.  Much like the placeholder attribute's introduction to markup, a frequently used...

Discussion

  1. Salman Abbas

    Usually I hide my privates like this but when using Backbonejs I just use underscore prefixed method names so that child classes can inherit those methods.

  2. Could you include an example of usage of the first class? Thanks a lot :)

  3. I think there’s a typo in the last example:

    .success(function(res) {
            callback(handleResult());
          });
        }
    

    Shouldn’t res be passed to handleResult?

    .success(function(res) {
            callback(handleResult(res));
          });
        }
    

    Also, echoing @REINE, it would be great if you could provide usage examples throughout as you did first closure.

  4. When programming with prototypes (“classes”) it can be tough to enforce good scope and write good code. That is, in your first example, you define a function within a function. While there’s nothing illegal about this, it’s not especially efficient, since the function is actually going to be created as a totally new function (not just a separate stack frame) every time you create an instance of that prototype.

    This would definitely scale badly if this class had a lot of private “methods” and you created a lot of instances of it. There are two ways to avoid this, and neither are ideal.

    First, you can create the prototype itself inside a closure, and refer to functions that are defined in the closure, but outside the prototype. This is bad because the functions have no scope. You would have to invoke them with the context every time, e.g.

    somePrivateFunc.apply(this,args);
    

    This is ugly and a pain. The other way is to include them in the prototype, and use some convention to identify them as private (like an underscore prefixing the name). I do this a lot. While you do open yourself up to abuse since there’s nothing stopping any user of the “class” to access those methods, let’s remember this is javascript: anyone can always monkey patch your stuff and do whatever they want. It’s impossible to stop abuse if that is the goal.

    I think you have to decide what lengths you’ll go to to enforce good code writing. I usually fall in “I want stuff on the prototype” for complex classes because it’s too risky and difficult to manage other ways.

  5. gby

    That’s exactly why many programmers with experience in better languages hate JS. Things that should be obvious (build into the very syntax of the language ) need patterns and tricks. That sucks, badly. In any big enough project you have to do so many things that thinking about how to make variable private is ridiculous waste of time and money. Don’t get me wrong, I know JS and I use it a lot. I just wish there would be some alternative…

  6. Aale

    Yes JavaScript sucks but not because it exposes its privates.
    Why should it be a big problem to expose them?
    You/team write the code with full knowledge of what is what.
    “ it’s fair game for anyone “
    SO WHAT…
    Jamie hit the nail on the head when he mentioned about what people can do with your script.
    When it goes public you just have to worry that it works correctly. NOT to impress your peers…
    YOU just make sure you the developer understand what you are doing…
    With all that said…
    Yes we need good structure in a language and peer reviews are just one way to achieve that.

  7. Jos

    @Aale: maybe you should rephrase your contribution to something like “Sorry, but I am a rookie and at this moment I do not understand why hiding of variables is necessary, maybe anyone can give me a clue and enlighten me?”

  8. Kamil Szot

    Please don’t hide your private methods. Namespace them by all means but leave a way to access them from outside.

    There’s nothing I hate more than not being able to compose parts of the library I’m using in ways API designer haven’t anticipated.

    At the moment I’ll need to compile my own version of d3js just because their creators hid d3_time_scale and related stuff.

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!

Recently on David Walsh Blog

  • Prevent Chrome from Translating a Page

    A while back I shared my favorite Google Chrome extension:  Google Art Project.  I've enjoyed seeing beautiful art when I open a new tab -- it's brought genuine happiness to my day, however small that happiness may be.  About a week ago, however, the art presented had...

  • Create Any Type Of Website With These Multi-Purpose Themes

    We have selected what we believe are the very best multipurpose WordPress themes on the market today. Our list contains a number of best sellers, several newcomers that are proving to be highly popular, and a few themes that are ideal for creating the types of...

  • An Introduction to Static Site Generators

    Static site generators seem to have been becoming more and more popular recently, but they’re not one of those ephemeral novelty things that grow in popularity as quickly as they fall into oblivion shortly after. For over a decade, many different projects — 394 of...

  • Automated Tests for Visual Responsive Layouts

    Today it's all about testing. In 2015, many developers knows about TDD and I personally think that testing is one of the key for quality products. But what about testing in a Front-end environment? How do you guys write your tests for a responsive page or...

  • Getting Dicey With Flexbox

    What if you could build complex CSS layouts in minutes? Flexbox is a new CSS layout spec that makes it easy to construct dynamic layouts. With flexbox, vertical centering, same-height columns, reordering, and direction agnosticism are a piece of cake. There's a popular myth floating around that...