JavaScript private methods

前端 未结 30 1508
-上瘾入骨i
-上瘾入骨i 2020-11-22 08:16

To make a JavaScript class with a public method I\'d do something like:

function Restaurant() {}

Restaurant.prototype.buy_food = function(){
   // something         


        
相关标签:
30条回答
  • 2020-11-22 08:46

    This is what I worked out:

    Needs one class of sugar code that you can find here. Also supports protected, inheritance, virtual, static stuff...

    ;( function class_Restaurant( namespace )
    {
        'use strict';
    
        if( namespace[ "Restaurant" ] ) return    // protect against double inclusions
    
            namespace.Restaurant = Restaurant
        var Static               = TidBits.OoJs.setupClass( namespace, "Restaurant" )
    
    
        // constructor
        //
        function Restaurant()
        {
            this.toilets = 3
    
            this.Private( private_stuff )
    
            return this.Public( buy_food, use_restroom )
        }
    
        function private_stuff(){ console.log( "There are", this.toilets, "toilets available") }
    
        function buy_food     (){ return "food"        }
        function use_restroom (){ this.private_stuff() }
    
    })( window )
    
    
    var chinese = new Restaurant
    
    console.log( chinese.buy_food()      );  // output: food
    console.log( chinese.use_restroom()  );  // output: There are 3 toilets available
    console.log( chinese.toilets         );  // output: undefined
    console.log( chinese.private_stuff() );  // output: undefined
    
    // and throws: TypeError: Object #<Restaurant> has no method 'private_stuff'
    
    0 讨论(0)
  • 2020-11-22 08:47

    Personally, I prefer the following pattern for creating classes in JavaScript :

    var myClass = (function() {
        // Private class properties go here
    
        var blueprint = function() {
            // Private instance properties go here
            ...
        };
    
        blueprint.prototype = { 
            // Public class properties go here
            ...
        };
    
        return  {
             // Public class properties go here
            create : function() { return new blueprint(); }
            ...
        };
    })();
    

    As you can see, it allows you to define both class properties and instance properties, each of which can be public and private.


    Demo

    var Restaurant = function() {
        var totalfoodcount = 0;        // Private class property
        var totalrestroomcount  = 0;   // Private class property
        
        var Restaurant = function(name){
            var foodcount = 0;         // Private instance property
            var restroomcount  = 0;    // Private instance property
            
            this.name = name
            
            this.incrementFoodCount = function() {
                foodcount++;
                totalfoodcount++;
                this.printStatus();
            };
            this.incrementRestroomCount = function() {
                restroomcount++;
                totalrestroomcount++;
                this.printStatus();
            };
            this.getRestroomCount = function() {
                return restroomcount;
            },
            this.getFoodCount = function() {
                return foodcount;
            }
        };
       
        Restaurant.prototype = {
            name : '',
            buy_food : function(){
               this.incrementFoodCount();
            },
            use_restroom : function(){
               this.incrementRestroomCount();
            },
            getTotalRestroomCount : function() {
                return totalrestroomcount;
            },
            getTotalFoodCount : function() {
                return totalfoodcount;
            },
            printStatus : function() {
               document.body.innerHTML
                   += '<h3>Buying food at '+this.name+'</h3>'
                   + '<ul>' 
                   + '<li>Restroom count at ' + this.name + ' : '+ this.getRestroomCount() + '</li>'
                   + '<li>Food count at ' + this.name + ' : ' + this.getFoodCount() + '</li>'
                   + '<li>Total restroom count : '+ this.getTotalRestroomCount() + '</li>'
                   + '<li>Total food count : '+ this.getTotalFoodCount() + '</li>'
                   + '</ul>';
            }
        };
    
        return  { // Singleton public properties
            create : function(name) {
                return new Restaurant(name);
            },
            printStatus : function() {
              document.body.innerHTML
                  += '<hr />'
                  + '<h3>Overview</h3>'
                  + '<ul>' 
                  + '<li>Total restroom count : '+ Restaurant.prototype.getTotalRestroomCount() + '</li>'
                  + '<li>Total food count : '+ Restaurant.prototype.getTotalFoodCount() + '</li>'
                  + '</ul>'
                  + '<hr />';
            }
        };
    }();
    
    var Wendys = Restaurant.create("Wendy's");
    var McDonalds = Restaurant.create("McDonald's");
    var KFC = Restaurant.create("KFC");
    var BurgerKing = Restaurant.create("Burger King");
    
    Restaurant.printStatus();
    
    Wendys.buy_food();
    Wendys.use_restroom();
    KFC.use_restroom();
    KFC.use_restroom();
    Wendys.use_restroom();
    McDonalds.buy_food();
    BurgerKing.buy_food();
    
    Restaurant.printStatus();
    
    BurgerKing.buy_food();
    Wendys.use_restroom();
    McDonalds.buy_food();
    KFC.buy_food();
    Wendys.buy_food();
    BurgerKing.buy_food();
    McDonalds.buy_food();
    
    Restaurant.printStatus();

    See also this Fiddle.

    0 讨论(0)
  • 2020-11-22 08:49

    Here is the class which I created to understand what Douglas Crockford's has suggested in his site Private Members in JavaScript

    function Employee(id, name) { //Constructor
        //Public member variables
        this.id = id;
        this.name = name;
        //Private member variables
        var fName;
        var lName;
        var that = this;
        //By convention, we create a private variable 'that'. This is used to     
        //make the object available to the private methods. 
    
        //Private function
        function setFName(pfname) {
            fName = pfname;
            alert('setFName called');
        }
        //Privileged function
        this.setLName = function (plName, pfname) {
            lName = plName;  //Has access to private variables
            setFName(pfname); //Has access to private function
            alert('setLName called ' + this.id); //Has access to member variables
        }
        //Another privileged member has access to both member variables and private variables
        //Note access of this.dataOfBirth created by public member setDateOfBirth
        this.toString = function () {
            return 'toString called ' + this.id + ' ' + this.name + ' ' + fName + ' ' + lName + ' ' + this.dataOfBirth; 
        }
    }
    //Public function has access to member variable and can create on too but does not have access to private variable
    Employee.prototype.setDateOfBirth = function (dob) {
        alert('setDateOfBirth called ' + this.id);
        this.dataOfBirth = dob;   //Creates new public member note this is accessed by toString
        //alert(fName); //Does not have access to private member
    }
    $(document).ready()
    {
        var employee = new Employee(5, 'Shyam'); //Create a new object and initialize it with constructor
        employee.setLName('Bhaskar', 'Ram');  //Call privileged function
        employee.setDateOfBirth('1/1/2000');  //Call public function
        employee.id = 9;                     //Set up member value
        //employee.setFName('Ram');  //can not call Private Privileged method
        alert(employee.toString());  //See the changed object
    
    }
    
    0 讨论(0)
  • 2020-11-22 08:53

    All of this closure will cost you. Make sure you test the speed implications especially in IE. You will find you are better off with a naming convention. There are still a lot of corporate web users out there that are forced to use IE6...

    0 讨论(0)
  • 2020-11-22 08:54

    You can do it, but the downside is that it can't be part of the prototype:

    function Restaurant() {
        var myPrivateVar;
    
        var private_stuff = function() {  // Only visible inside Restaurant()
            myPrivateVar = "I can set this here!";
        }
    
        this.use_restroom = function() {  // use_restroom is visible to all
            private_stuff();
        }
    
        this.buy_food = function() {   // buy_food is visible to all
            private_stuff();
        }
    }
    
    0 讨论(0)
  • 2020-11-22 08:54

    Wrap all code in Anonymous Function: Then , all functions will be private ,ONLY functions attached to window object :

    (function(w,nameSpacePrivate){
         w.Person=function(name){
             this.name=name;   
             return this;
         };
    
         w.Person.prototype.profilePublic=function(){
              return nameSpacePrivate.profile.call(this);
         };  
    
         nameSpacePrivate.profile=function(){
           return 'My name is '+this.name;
         };
    
    })(window,{});
    

    Use this :

      var abdennour=new Person('Abdennour');
      abdennour.profilePublic();
    

    FIDDLE

    0 讨论(0)
提交回复
热议问题