JavaScript private methods

2018-12-31 10:38发布

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

function Restaurant() {}

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

Restaurant.prototype.use_restroom = function(){
   // something here
}

That way users of my class can:

var restaurant = new Restaurant();
restaurant.buy_food();
restaurant.use_restroom();

How do I create a private method that can be called by the buy_food and use_restroom methods but not externally by users of the class?

In other words, I want my method implementation to be able to do:

Restaurant.prototype.use_restroom = function() {
   this.private_stuff();
}

But this shouldn't work:

var r = new Restaurant();
r.private_stuff();

How do I define private_stuff as a private method so both of these hold true?

I've read Doug Crockford's writeup a few times but it doesn't seem like "private" methods can be called by public methods and "privileged" methods can be called externally.

29条回答
若你有天会懂
2楼-- · 2018-12-31 10:48
var TestClass = function( ) {

    var privateProperty = 42;

    function privateMethod( ) {
        alert( "privateMethod, " + privateProperty );
    }

    this.public = {
        constructor: TestClass,

        publicProperty: 88,
        publicMethod: function( ) {
            alert( "publicMethod" );
            privateMethod( );
        }
    };
};
TestClass.prototype = new TestClass( ).public;


var myTestClass = new TestClass( );

alert( myTestClass.publicProperty );
myTestClass.publicMethod( );

alert( myTestClass.privateMethod || "no privateMethod" );

Similar to georgebrock but a little less verbose (IMHO) Any problems with doing it this way? (I haven't seen it anywhere)

edit: I realised this is kinda useless since every independent instantiation has its own copy of the public methods, thus undermining the use of the prototype.

查看更多
临风纵饮
3楼-- · 2018-12-31 10:49

Private functions cannot access the public variables using module pattern

查看更多
临风纵饮
4楼-- · 2018-12-31 10:51

If you want the full range of public and private functions with the ability for public functions to access private functions, layout code for an object like this:

function MyObject(arg1, arg2, ...) {
  //constructor code using constructor arguments...
  //create/access public variables as 
  // this.var1 = foo;

  //private variables

  var v1;
  var v2;

  //private functions
  function privateOne() {
  }

  function privateTwon() {
  }

  //public functions

  MyObject.prototype.publicOne = function () {
  };

  MyObject.prototype.publicTwo = function () {
  };
}
查看更多
爱死公子算了
5楼-- · 2018-12-31 10:51

Since everybody was posting here his own code, I'm gonna do that too...

I like Crockford because he introduced real object oriented patterns in Javascript. But he also came up with a new misunderstanding, the "that" one.

So why is he using "that = this"? It has nothing to do with private functions at all. It has to do with inner functions!

Because according to Crockford this is buggy code:

Function Foo( ) {
    this.bar = 0; 
    var foobar=function( ) {
        alert(this.bar);
    }
} 

So he suggested doing this:

Function Foo( ) {
    this.bar = 0;
    that = this; 
    var foobar=function( ) {
        alert(that.bar);
    }
}

So as I said, I'm quite sure that Crockford was wrong his explanation about that and this (but his code is certainly correct). Or was he just fooling the Javascript world, to know who is copying his code? I dunno...I'm no browser geek ;D

EDIT

Ah, that's what is all about: What does 'var that = this;' mean in JavaScript?

So Crockie was really wrong with his explanation....but right with his code, so he's still a great guy. :))

查看更多
爱死公子算了
6楼-- · 2018-12-31 10:52

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

查看更多
妖精总统
7楼-- · 2018-12-31 10:53
Class({  
    Namespace:ABC,  
    Name:"ClassL2",  
    Bases:[ABC.ClassTop],  
    Private:{  
        m_var:2  
    },  
    Protected:{  
        proval:2,  
        fight:Property(function(){  
            this.m_var--;  
            console.log("ClassL2::fight (m_var)" +this.m_var);  
        },[Property.Type.Virtual])  
    },  
    Public:{  
        Fight:function(){  
            console.log("ClassL2::Fight (m_var)"+this.m_var);  
            this.fight();  
        }  
    }  
});  

https://github.com/nooning/JSClass

查看更多
登录 后发表回答