Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Page 1 of 3 123 LastLast
Results 1 to 15 of 35
  1. #1
    New Coder
    Join Date
    Oct 2011
    Posts
    25
    Thanks
    0
    Thanked 0 Times in 0 Posts

    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,

    S

  • #2
    Supreme Master coder! Philip M's Avatar
    Join Date
    Jun 2002
    Location
    London, England
    Posts
    17,910
    Thanks
    203
    Thanked 2,531 Times in 2,509 Posts
    Are you sure you mean Javascript - not Java? Java and Javascript are entirely different programming languages, in spite of the confusingly similar names. Rather like Austria and Australia!

    It's important to note that there are no classes in JavaScript. Functions can be used to somewhat simulate classes, but in general JavaScript is a class-less language. Everything is an object. And when it comes to inheritance, objects inherit from objects, not classes from classes as in the "class"-ical languages.

    All the code given in this post has been tested and is intended to address the question asked.
    Unless stated otherwise it is not just a demonstration.

  • #3
    New Coder
    Join Date
    Oct 2011
    Posts
    25
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Quote Originally Posted by Philip M View Post
    Are you sure you mean Javascript - not Java? Java and Javascript are entirely different programming languages, in spite of the confusingly similar names. Rather like Austria and Australia!

    It's important to note that there are no classes in JavaScript. Functions can be used to somewhat simulate classes, but in general JavaScript is a class-less language. Everything is an object. And when it comes to inheritance, objects inherit from objects, not classes from classes as in the "class"-ical languages.
    No, I do mean Javascript. They have a "new" keyword and constructors etc etc etc. They also have functions (call them methods if you prefer) and properties.

    I currently have a class that is a suite of functions that maintain a user table. I do not want ANY of the internals of that object to be visible to the outside world unless I explicitly say so. Currently, they is a significant danger of name clashes and data corruption and general chaos.

    Hence my question.

    S

  • #4
    Supreme Master coder! Philip M's Avatar
    Join Date
    Jun 2002
    Location
    London, England
    Posts
    17,910
    Thanks
    203
    Thanked 2,531 Times in 2,509 Posts
    Suggest you Google for "Javascript scope" and look at the several articles posted, e.g.
    http://www.digital-web.com/articles/...in_javascript/

    All the code given in this post has been tested and is intended to address the question asked.
    Unless stated otherwise it is not just a demonstration.

  • #5
    Senior Coder chump2877's Avatar
    Join Date
    Dec 2004
    Location
    the U.S. of freakin' A.
    Posts
    2,773
    Thanks
    19
    Thanked 155 Times in 146 Posts
    I do not want ANY of the internals of that object to be visible to the outside world unless I explicitly say so. Currently, they is a significant danger of name clashes and data corruption and general chaos.
    Pseudo-class with all "private" members:

    Code:
    function PseudoClass()
    {
    	// "private" properties
    	var property1 = "foo";
    	var property2 = "bar";
    	
    	// "private" methods
    	var someMethod = function()
    	{
    		// Do Something
    	};
    	
    	// pseudo constructor
    	var constructor = function()
    	{
    		// Do Something on instantiation
    		someMethod();
    	};
    	constructor();
    }
    
    var cs = new PseudoClass;
    Keep in mind that JS is inherently "not" private in that anyone can see your code n the browser. But if all of your "class" properties and methods are "local" to PseudoClass, then at least you don't have to worry about naming conflicts with other variables/functions in the global namespace...
    Last edited by chump2877; 12-31-2011 at 11:34 AM.
    Regards, R.J.

    ---------------------------------------------------------

    Help spread the word! Like my YouTube-to-Mp3 Conversion Script on Facebook !! :)
    [Related videos and tutorials are also available at my YouTube channel and on Dailymotion]
    Get free updates about new software version releases, features, and bug fixes!

  • #6
    New Coder
    Join Date
    Oct 2011
    Posts
    25
    Thanks
    0
    Thanked 0 Times in 0 Posts

    After some research

    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:
    Code:
    <!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

    Code:
    // 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
    // functios. 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:

    Code:
    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

  • #7
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    25,155
    Thanks
    75
    Thanked 4,338 Times in 4,304 Posts
    Ummm...isn't that exactly what RJ showed you in post #5?

    But it's still not a "class" in any classical sense of the word. Not when compared to classes in languages such as Java and C++ and C# and ...
    An optimist sees the glass as half full.
    A pessimist sees the glass as half empty.
    A realist drinks it no matter how much there is.

  • #8
    New Coder
    Join Date
    Oct 2011
    Posts
    25
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Quote Originally Posted by Old Pedant View Post
    Ummm...isn't that exactly what RJ showed you in post #5?

    But it's still not a "class" in any classical sense of the word. Not when compared to classes in languages such as Java and C++ and C# and ...
    It is a broader examination of the issue with extensive comments designed to help others.

    Whether it is a class or not matters only in as much as the word is loaded with meaning from other languages and products. As long as it does what you want, what you call it is totally irrelevant.

    I can instantiate it.
    I can activate functions within it.
    I can update data properties.
    I can make items public or private.

    That's all I really need.

  • #9
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    25,155
    Thanks
    75
    Thanked 4,338 Times in 4,304 Posts
    I'm not at all clear why you classified "retainer variables" as anything special. In essesnce, they are simply private variables that are exposed via public methods. No? What am I missing?

    Wouldn't it make as much sense to provide "safe" setter/getter methods and so follow the same patterns as are used in languages such as Java?
    Code:
    function pseudoClass( )
    {
         var private;
         this.getPrivate = function() { return private; };
         this.setPrivate = function(value) { if ( ! isNaN(value) ) private = value; };
    }
    In what way is private here different than a "retainer variable" as you defined it?
    An optimist sees the glass as half full.
    A pessimist sees the glass as half empty.
    A realist drinks it no matter how much there is.

  • #10
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    25,155
    Thanks
    75
    Thanked 4,338 Times in 4,304 Posts
    Of course, one problem with JavaScript is that you can't guarantee that your "classes" will work correctly.

    For example:
    Code:
    TestClass.prototype.privateFunction = function() { return "aha"; }
    var t = new TestClass();
    alert( t.privateFunction() );
    (Yeah, I know...the idiot who does that deserves what he gets. But still, it's a flaw in the ability to completely encapsulate your "private" coding.)
    An optimist sees the glass as half full.
    A pessimist sees the glass as half empty.
    A realist drinks it no matter how much there is.

  • #11
    New Coder
    Join Date
    Oct 2011
    Posts
    25
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Quote Originally Posted by Old Pedant View Post
    I'm not at all clear why you classified "retainer variables" as anything special. In essesnce, they are simply private variables that are exposed via public methods. No? What am I missing?

    Nothing - they are the same - see the comment on the deceleration of myNumber:

    Code:
    var myNumber = null; // The retainer variable (note that it is private)
    The difference here is not the nature of the variable but of the manner in which it "retains" its value across function calls. It is a technique rather than a language property. It seemed a useful one to me, which is why I elected to include in the demo.


    Wouldn't it make as much sense to provide "safe" setter/getter methods and so follow the same patterns as are used in languages such as Java?
    Code:
    function pseudoClass( )
    {
         var private;
         this.getPrivate = function() { return private; };
         this.setPrivate = function(value) { if ( ! isNaN(value) ) private = value; };
    }
    I only show what is possible. I don't dictate approach. Get and Set are fine by me. Just so long as what is going on is understood and not followed blindly. Javascript is different to Java etc - and I created the demo to highlight some of these differences for the purposes of sharing.

    In what way is private here different than a "retainer variable" as you defined it?

    See above.
    Please see my comments above

  • #12
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    25,155
    Thanks
    75
    Thanked 4,338 Times in 4,304 Posts
    Okay...valid arguments. I admit to trying to keep things as simple as possible, so I tend to try to cut to the lowest common denominator.

    I also admit to not using JavaScript for much serious work. 95% of the stuff I do is done server side with JavaScript just used as a GUI assistance mechanism.
    An optimist sees the glass as half full.
    A pessimist sees the glass as half empty.
    A realist drinks it no matter how much there is.

  • #13
    Senior Coder chump2877's Avatar
    Join Date
    Dec 2004
    Location
    the U.S. of freakin' A.
    Posts
    2,773
    Thanks
    19
    Thanked 155 Times in 146 Posts
    If you're going to make class members public, then you will also want to consider adding to the prototype as well:

    "Prototype is a type of inheritance in JavaScript. We use it when we would like an object to inherit a method after it has been defined. Think of prototyping mentally as "attaching" a method to an object after it's been defined, in which all object instances then instantly share." (excerpt from here)

    If you are creating a lot of instances of your class (i.e., object factory pattern), I believe that prototype is more efficient (in terms of memory usage) than the privileged/public methods that you demonstrated in your example. Because each instance of your class carries around one more member inside of it that could have been designated only once to prototype. (I can't find any documentation on this a the moment, but like I said, i believe this is the case?...)

    Edit...
    Here we go: http://codebetter.com/petervanooijen...-to-prototype/
    Check the blurb under the "What's the cost ?" subhead on the page about prototype and memory usage.

    In other words, the most scalable approach to javascript oop (in terms of memory efficiency) is to use private members and prototype (for public members) only -- and don't use public/privileged "instance" methods if you dont have to.
    Last edited by chump2877; 01-02-2012 at 09:13 AM.
    Regards, R.J.

    ---------------------------------------------------------

    Help spread the word! Like my YouTube-to-Mp3 Conversion Script on Facebook !! :)
    [Related videos and tutorials are also available at my YouTube channel and on Dailymotion]
    Get free updates about new software version releases, features, and bug fixes!

  • #14
    New Coder
    Join Date
    Oct 2011
    Posts
    25
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Quote Originally Posted by Old Pedant View Post
    Okay...valid arguments. I admit to trying to keep things as simple as possible, so I tend to try to cut to the lowest common denominator.

    I also admit to not using JavaScript for much serious work. 95% of the stuff I do is done server side with JavaScript just used as a GUI assistance mechanism.
    That's perfectly fine Old Pedant - I always try and keep things as simple as possible and I completely agree with you that one should. But I do believe it is very important that one understands the programming model before the syntax because I feel it is only in that way that one can keep things simple. That's why, after my research, I thought I would share my findings with other folk on the forum in a bid to help them.

    The split twixt client and server is a huge topic on its own and one of high interest.

    I am building an app that has a UI that mimics a regular C++ or Java UI (not because I like them, just for the purposes of standardisation). The app also makes extensive use of asynchronous Ajax calls. So precisely where to draw the client server line is something that exercises me daily.

    I do appreciate your questioning my post - it is good to be challenged. But I also hope it may shed a modicum of light.

    Good to chat to you.

    S

  • #15
    New Coder
    Join Date
    Oct 2011
    Posts
    25
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Quote Originally Posted by chump2877 View Post
    If you're going to make class members public, then you will also want to consider adding to the prototype as well:

    "Prototype is a type of inheritance in JavaScript. We use it when we would like an object to inherit a method after it has been defined. Think of prototyping mentally as "attaching" a method to an object after it's been defined, in which all object instances then instantly share." (excerpt from here)

    If you are creating a lot of instances of your class (i.e., object factory pattern), I believe that prototype is more efficient (in terms of memory usage) than the privileged/public methods that you demonstrated in your example. Because each instance of your class carries around one more member inside of it that could have been designated only once to prototype. (I can't find any documentation on this a the moment, but like I said, i believe this is the case?...)

    Edit...
    Here we go: http://codebetter.com/petervanooijen...-to-prototype/
    Check the blurb under the "What's the cost ?" subhead on the page about prototype and memory usage.

    In other words, the most scalable approach to javascript oop (in terms of memory efficiency) is to use private members and prototype (for public members) only -- and don't use public/privileged "instance" methods if you dont have to.
    Thank you.

    I deliberately omitted to mention prototype. For singleton "classes" I am struggling to think of why I would use it.

    For factory objects it may be different. But let's think about it for a moment. As far as I know the use of prototype allows object instances to share the implementation of the prototype members not the values. The values must be specific to the instances so I am not entirely sure what performance gains are to be had. Even if there are gains, what effective difference would they make I wonder?

    I also think that prototype may (I only say "may") lead to bad practice. Why do you want to attach (call it inherit if you wish) a method to an object at run time. Why have we not designed our "classes" correctly ahead of time? We would have to do it using Java (extend) in order to benefit from that language's implementation of inheritance !!

    I would be interested to hear of any answers to this.

    Good discussion - thanks.

    S


  •  
    Page 1 of 3 123 LastLast

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •