如果您只想要“私有”方法,那么您定义它的模式是错误的。我认为可以访问“私有”方法的方法称为特权方法,但可能是错误的。
创建它们的模式如下(在示例中添加了实例变量和继承):
// added to show inheritance
var Parent = function(){
//instance members
this.parentInstanceVar=["parent"];
};
var Class = function() {
//1st step to "inherrit" from Parent
// take ownership of Parent instance members
Parent.call(this);
//to pass all arguments to Parent constructor:
//Parent.apply(this,arguments);
//to pass specific agruemtns to Parent
//Parent.call(this,arg1,arg5);
this.someIntanceVar=["Class instance"];
};
Class.prototype=(function(parent){
var ret=(parent&&parent.prototype)?
Object.create(parent.prototype):
Object.create({});
//repair the constructor
ret.constructor=Class;
var myPrivateMethod = function() {
return this.someIntanceVar;
};
//privileged method calling "private method"
ret.myPriviligedMethod=function(){
return myPrivateMethod.call(this);
};
return ret;
}(Parent));//2nd step to "inherit" from Parent
//non privileged method
Class.prototype.nonPrivileged=function(){
//can't accesss myPrivateMethod here
};
//some tests creating 2 instances
var c1=new Class();
var c2=new Class();
c1.parentInstanceVar.push("added in c1");
c1.someIntanceVar.push("added in c1");
console.log(c2.parentInstanceVar);//=["parent"]
console.log(c2.someIntanceVar);//=["class instance"]
console.log(c1.myPriviligedMethod());//=["Class instance", "added in c1"]
console.log(c2.myPriviligedMethod());//=["Class instance"]
//reason why we repaired the constructor:
console.log((new c1.constructor()) instanceof Class);//=true
此模式仅处理实例共享私有成员。如果您需要特定于实例的私有成员,则不能将原型用于任何特权方法(需要访问“私有”实例特定成员的方法)。你可以使用一个函数来返回一个包含闭包的对象,但我真的不会使用这种模式,因为它忽略了原型和它带来的好处,使测试变得更加困难,并且是一个巨大的克隆痛苦。
var createClass=function(privateInstanceVal){
var privateMethod=function(val){
privateInstanceVal.push(val);
return privateInstanceVal;
};
return{
publicInstanceVar:[],
publicMethod:function(val){return privateMethod(val);}
}
};
c1=createClass([]);
var b = c1.publicMethod(33);
console.log("b is:",b);
b.push("because I returned the private I made it public");
console.log(c1.publicMethod(0));//=[33, "because ... public", 0]
该示例显示了有时通过返回您将其公开的“私人”而犯的错误。相反,您可以返回一个副本:return privateInstanceVal.concat([]);