Private Javascript Classes

Hi Guys,

What is the best way to create a javascript class that has all its methods and properties private unless I want them to be public?

Many thanks for any help,

You can do this format:


var obj = function() {
	var _privProp = 'str';
	
	function _privMethodOne() {
		return 'Hello from _privMethodOne';
	}
	function _privMethodTwo() {}
	
	return {
		// public & privileged properties & methods
		privl_Prop	: _privProp,
		privl_MethOne	: _privMethodOne,
		pubFunc		: function() {
			return 'I\\'m a public function';	
		}
	}	
}

var Obj = new obj;
// str
	console.log(Obj.privl_Prop); 

// Errors out
//	console.log(Obj._privMethodOne());
//	console.log(Obj._privMethodTwo());

// Hello from _privMethodOne
	console.log(Obj.privl_MethOne());			

// I'm a public function		
	console.log(Obj.pubFunc());	

More reading can be done at these sites:
http://javascript.crockford.com/private.html
http://www.dustindiaz.com/javascript-private-public-privileged/

Hi guys,

After some research I have uncovered quite a bit of interesting information. So I have wrapped it all up into a demo, which may be found below. Comments and improvements welcome. Hope it is of some use to anyone coming across this thread.

S

A simple html page:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

  <head>
  <title>eazyGen - Testing</title>

<script type="text/javascript">
window.onerror=function(msg, url, linenumber){
 alert("Error message: " + msg + " URL: " + url + " Line Number: " + linenumber)
 return true
}
</script>
    <script type="text/javascript" src="TestClass.js"></script>
    <script type="text/javascript" src="testHarness.js"></script>

</head>
<body>
</body>

A test harness



// This demo shows the difference between member (data) and function (activity) types in Javascript
// It creates a new instance of the TestClass and then demonstrates what is available
// publicly, privately, and also statically.
//
// Using these techniques will help you write more robust and error free Javascript code
// If anyone sees an error or knows of a better way, please let me know
//
// But please bear in mind that this code has been designed with usability
// in mind as opposed to technical brilliance.
//
// www.eazyGen.com


// Create new instance of the class
test = new TestClass();

// Why? Many reasons:
// A class allows us to have several instances of the same class (objects)
// A class allows us to re-use the code within it without having to code it mroe than once
// A class can allow us to have a robust interface to the data and fuctions within it
// which makes coding easier



// A private member is available within the instance (private) but not outside (public)
alert("Show the private variable : " + test.privateField ); // Shows undefined
// Why?
// A private variable should be just that - private. It may not be changed by anything other
// than the class instances. This ensures that the data cannot be corrupted by mistake



// A public member is available within the instance (private) AND outside (public)
alert("Show the public variable : " + test.publicField); // Shows correct value
// Why?
// There are times when we DO want to change the data inside an object, although
// it may be better to only change this data via a call to a fucntion.
// But this shows how it may be changed by an external function
test.publicField = "I have now changed";
alert("Show the public variable again : " + test.publicField); // Shows new value




// A private function is a fuction that is only available to the class instance (private)
//and may NOT be called from outside (public)
//test.privateFunction() // This would result in a Javascript run time error



// A public function is a fuction that is available publicly
//and may NOT be called from outside (public)
test.publicFunction() // This works


// A privileged function is available publicly, but which also has access to private variables
alert("Show the private variable : " + test.secondPrivateField); // Shows undefined
alert("Show the private variable via a privileged  function: " + test.privilegedFunction()); // Shows correct value
// Why?
// A public fuctio allows us to invoke actions, but it is perfectly reasonable to allow
// private data to be made available to public functions. In this way we can alter the values
// of private variables, but oly using the formal functions (or methods) of the class object
// This is good general OO practice.
// Now we will call a public function that alters the private variable
alert("Show the changed private variable : " + test.secondPrivilegedFunction()); // Shows changed value
// Note - I have called these functions "privileged" but, in truth, they are just standard
// functions. But I show them this way to demonstrate how they can manipulate private data



// Retainer variables
// Retainer variables are variables that retain their value between function calls
// This property can be useful when, for example, you want to keep
// track of how many times a function has been called from within the function
// NOTE – I call these  “Retainer” variables and NOT “Static” variables,
// because that could confuse them with Static variables in other, more
// OO languages – Java, C++ etc
// They are not the same thing. Static variables in Java and co keep
// track of their value across instances of a class. Retainer variables
// keep track of their value across function calls – which is different
//
// Javascript does NOT support Static variables as used in Java
//
// An alternative would be to use global variables, but retainer variables
// are an improvement on this I believe because they can be kept private and unchangeable
test.staticVariableFuction(); // Returns 1
test.staticVariableFuction(); // Returns the incremented value

// Of course, there is a lot more to this subject, but I hope some of that has been useful.

And a class to operate upon:

function TestClass () { // Declare the class and construct



    // This is a PRIVATE field variable only available within constructor
    var privateField = "My PRIVATE Field Variable";



    // This is a PUBLIC field variable only available within constructor
    this.publicField = "My PUBLIC Field Variable";



    // A Private function
    var privateFunction = function () { // A private function
        alert("This is NOT publicly available");
    } // End A private function



    // A Public function
    this.publicFunction = function () { // A public function
        alert("This IS a publicly available function");
    } // End A public function




    // This is a privileged function - one available publicly but which also has access
    // to private variable
    this.privilegedFunction = function () {
        alert("priv function - var is : " + myVar);
    }

    // This is another private field variable
    var secondPrivateField = "Also private";
    // This is a public function that gives access to the private field
    this.privilegedFunction = function () { // A privileged function
        return secondPrivateField;
    } // A privileged function

    // This is another priviledged function
    this.secondPrivilegedFunction = function () { // A second privileged function
        secondPrivateField = "Now I have changed too";
        return secondPrivateField;
    } // A second privileged function



     var myNumber = null; // The retainer variable (not that it is private)
     this.staticVariableFuction = function () { // Static variable function
        // Check to see if the variable has been initialized
        if (typeof myNumber == null) { // First time?
            // This is the first invokation so let us initialise the "static" variable "number"
            myNumber = 0;
        } // End First time?
        // increment the value
        myNumber = myNumber + 1;
        alert("The Number is : " + myNumber);
    } // End Static variable function


}// End Declare the class and construct


While the above code you posted is quite simple my question to you would be is “Do you understand exactly what is going on?”, the reason i ask is because the way you worded your post makes it sound like you just copied and pasted the code without fully understand the entire concept of how it and scopes work.

I wrote every single line of that code this morning. If you can find a copy on the web, please post a link.

The fact that the code is simple is due to the fact that I know exactly what is going on.

Try simplifying something you don’t understand and see how you get on.

S

No problem, just wanted to make sure as i don’t believe in the copy and paste technique :slight_smile:

Amen to that my friend :slight_smile:

S