An Information Hiding Proposal for ECMAScript

December 10, 2010

in JavaScript,Web Standards

One of the goals for ECMAScript Harmony, the project to define the next versions of the JavaScript standard, is to make JavaScript a better language for writing complex application.  Better support for object-oriented encapsulation, information hiding, and abstraction should help JavaScript programmer deal with such applications.

Today, I’m going to talk specifically about a proposal for better information hiding in JavaScript.  As I use the term, information hiding means that an object should clearly separate its stable public interface from its private implementation details. Properties that exist solely as implementation details should be hidden from “users” of that object.

JavaScript today does not provide much support for information hiding.  All properties have public string names and there is no language mechanism to tag  public or private properties.  Some programmers use naming conventions as a very weak form of information hiding.  Programmers looking for a stronger form often abandon the use of implementation properties (and prototype inheritance) and use closure capture to represent implementation state.

When evolving a language to address some specific program, it is natural to look at how other languages approach that problem.  Many people are familiar with information hiding in C++ or Java and may assume that JavaScript should implement information hiding in that same familiar way. In those languages “private” is an attribute of a member (field or method) of a class.  It means that a private member is only accessible to other members of the same class. The fact that member definitions are encapsulated together as a class definitions is key to this approach to information hiding.

Java-like information hiding is not a particularly good match to the JavaScript object model where the structure of an object is much more dynamic and  methods functions can be dynamically associated or disassociated with an object and shared by many different kinds of objects.

Let’s look at a different approach to information hiding that may be a better fit to JavaScript. In this approach “private” is an attribute of a property name, rather than of an actual property.  Only code that knows a “private name” can use that name to create or access a property of any object. It is knowledge of the name that is controlled rather than accessibility to the property.

Let’s look at how this might look in code.  First assume that a private declaration creates a unique private name and associates it with a local identifier that provides access to that unique name:

private implDetail;

The local identifier can then be used to create object properties whose “key” is that unique private name and also to reference such properties:

function MyObj() {
   private implDetail;
   this.answer = function() {return this.implDetail};

Remember that the name of the property created above is not actually the string "implDetail" but instead it is a unique value that was created by the private declaration. The identifier implDetail is just a lexically scoped handle that is used to access that private name value. So:

var obj=new MyObj();
alert(obj.implDetail);  //"undefined"
alert(obj.answer());  //"42"

For the first alert, the message is "undefined" because obj does not have a property with the sting name "implDetail".  Instead it has a property with a private name that does not match that string. In the second alert the statement is not within the lexical scope of the private declaration  (within the constructor MyObj) so the property identifier implDetail does not correspond to the private name.  Finally, the third alert calls a method which does have access to the private name and it can return the value of the property.

This is a very powerful mechanism for adding information hiding to the JavaScript object model.  By following various usage patterns it is possible to implement the equivalent of both instance private and “class” private properties and also the equivalent of C++ friends visibility.  It can also be used to make extensions to built-in objects such as Object.prototype in a manner that is guaranteed not to collide with independently developed code that might try to make similar extensions.

A complete strawman proposal for this style of information hiding has been prepared for EcmaScript Harmony. It covers many more the technical details and provides many more complete examples of how the feature could be used.  Take a look and let me know what you think.  We’ll be discussing it in the standards committee but I’d like to get feedback from a broader range of JavaScript programmers. Does this proposal address your information hiding needs?  Does it fit well with the language as you use it?


Previous post:

Next post: