要创建一个带有公共方法的JavaScript类,我可以这样做:

function Restaurant() {}

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

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

这样,我类的用户就可以:

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

如何创建一个私有方法,可以由buy_food和use_restroom方法调用,但不能由类的用户外部调用?

换句话说,我希望我的方法实现能够做到:

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

但这是行不通的:

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

如何将private_stuff定义为私有方法,使两者都成立?

我读过Doug Crockford的文章几次,但它似乎不像“私有”方法可以被公共方法调用,而“特权”方法可以被外部调用。


当前回答

我知道有点晚了,但是这样怎么样?

var obj = function(){
    var pr = "private";
    var prt = Object.getPrototypeOf(this);
    if(!prt.hasOwnProperty("showPrivate")){
        prt.showPrivate = function(){
            console.log(pr);
        }
    }    
}

var i = new obj();
i.showPrivate();
console.log(i.hasOwnProperty("pr"));

其他回答

以下是迄今为止我最喜欢的关于javascript中的私有/公共方法/成员和实例化:

这是文章:http://www.sefol.com/?p=1090

下面是一个例子:

var Person = (function () {

    //Immediately returns an anonymous function which builds our modules 
    return function (name, location) {

        alert("createPerson called with " + name);

        var localPrivateVar = name;

        var localPublicVar = "A public variable";

        var localPublicFunction = function () {
            alert("PUBLIC Func called, private var is :" + localPrivateVar)
        };

        var localPrivateFunction = function () {
            alert("PRIVATE Func called ")
        };

        var setName = function (name) {

            localPrivateVar = name;

        }

        return {

            publicVar: localPublicVar,

            location: location,

            publicFunction: localPublicFunction,

            setName: setName

        }

    }
})();


//Request a Person instance - should print "createPerson called with ben"
var x = Person("ben", "germany");

//Request a Person instance - should print "createPerson called with candide"
var y = Person("candide", "belgium");

//Prints "ben"
x.publicFunction();

//Prints "candide"
y.publicFunction();

//Now call a public function which sets the value of a private variable in the x instance
x.setName("Ben 2");

//Shouldn't have changed this : prints "candide"
y.publicFunction();

//Should have changed this : prints "Ben 2"
x.publicFunction();

JSFiddle: http://jsfiddle.net/northkildonan/kopj3dt3/1/

将所有代码包装在匿名函数中:然后,所有函数将是私有的,只有函数附加到窗口对象:

(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,{});

用这个:

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

小提琴

这是我得出的结论:

需要一类糖代码,你可以在这里找到。还支持保护,继承,虚拟,静态的东西…

;( 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'

我想到了这个:编辑:实际上,有人已经链接到一个相同的解决方案。咄!

var Car = function() {
}

Car.prototype = (function() {
    var hotWire = function() {
        // Private code *with* access to public properties through 'this'
        alert( this.drive() ); // Alerts 'Vroom!'
    }

    return {
        steal: function() {
            hotWire.call( this ); // Call a private method
        },
        drive: function() {
            return 'Vroom!';
        }
    };
})();

var getAwayVechile = new Car();

hotWire(); // Not allowed
getAwayVechile.hotWire(); // Not allowed
getAwayVechile.steal(); // Alerts 'Vroom!'
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" );

类似于georgebrock,但不太啰嗦(恕我直言) 这样做有什么问题吗?(我哪儿都没见过)

编辑:我意识到这有点没用,因为每个独立的实例化都有自己的公共方法副本,从而破坏了原型的使用。