By making a distinction between what members of your object will be accessible to the outside world, you can enforce a much higher degree of control and avoid unpredictable behavior
In a previous post, I discussed how to create your own name-spaced JavaScript object. This is a highly recommended approach that keeps the global name space free of clutter and helps make your code easier to read and manage. When you create your own custom JavaScript object, by default, all members are public. This is generally not to your advantage. While wrapping all of your functionality in a custom object is a smart move, because all of its members are public, other code in the page that might be out of your control has full access to your object, which cold lead to problems.
Best practice is to make a clear distinction between which members of your object are public, and which members are private. The goal is to provide the absolute minimum access possible in order to allow your code to work as intended. This is known as “Principle of least privilege” or “Principle of least authority” (POLA).
In some programming languages, there are reserved words that easily provide scope for object or class members, such as “private”, “public”, “static” or “protected”. There is no built-in syntax that provides scope in JavaScript. Functions are the tool you use to provide scope and they do so very well. But because there is only one tool we have in-hand to create the desired scope for object members (or variables in general), there are a few techniques you need to use that allow you to use functions to create scope.
Example # 1:
|
var myObj = { myName : "Foo", myAddress : "123 E. Bar St." } console.log('My name is: ' + myObj.myName + ', My address is: ' + myObj.myAddress ); |
The output for Example # 1 would be: “My name is: Foo, My address is: 123 E. Bar St.”
This is not an optimal situation because all the members of our object are public. In order to create the desired scope, we can wrap all of the objects members in a function.
Example # 2:
|
var myObj = { data : function() { var myName = "Foo"; var myAdress = "123 E. Bar St."; } } console.log(myObj.data.myName + ', ' + myObj.data.myAddress); |
The output for Example # 2 would be: “undefined, undefined”
While we have made progress by wrapping the members in a function to provide scope, we have created another problem because these members are no longer publicly accessible. By using “var” when declaring the variables, they remain local to the function (good), but un-available to the outside world. The way to correct this is to create a public member that has privileged access to these private members.
Example # 3:
|
var myObj = { data : function() { var myName = "Foo", myAdress = "123 E. Bar St."; this.getMyName = function(){ return myName; } this.getMyAddress = function(){ return myAdress; } } } var obj = new myObj.data; console.log(obj.getMyName() + ', ' + obj.getMyAddress() ); |
The output for Example # 3 would be: “Foo, 123 E. Bar St.”
In Example # 3, the variable “obj” is set to the data member, inside of our object: “myObj”. By using the “this” keyword, we expose the members “getMyName” and “getMyAddress” publicly. While “getMyName” and “getMyAddress” are public methods, the variables “myName” and “myAddress” are still local, which means that they are private and not available outside of the member “data”. But, and here is the part that makes all work, “getMyName” and “getMyAddress” have complete access to all the private members of “data”. So “getMyName” and “getMyAddress” can return these private members, while they and anything else we want to protect, remain privately scoped.
Summary:
This is a very basic example, but the building blocks you need are all there. Creating a name-spaced global variable is a great approach that keeps the global name space clutter free. But, it is generally good practice to keep your object’s properties and methods private to whatever degree makes sense. Exposing the minimal number of members publicly is known as “Principle of least privilege” or “Principle of least authority”. By taking this approach, you keep your code safe from harm, easier to manage and also keep a tight leash on the behavior of your application.
Helpful Links regarding public and private Object members in JavaScript
http://javascript.crockford.com/private.html
http://stackoverflow.com/questions/55611/javascript-private-methods
http://stackoverflow.com/questions/483213/javascript-private-member-on-prototype
http://en.wikipedia.org/wiki/Principle_of_least_privilege