我在javascript中定义了一个充当类的函数。在其中,我定义了几个公共方法,但是有一个私有方法,我需要访问其中的一个公共方法。
function myClass(){
this.myPublicMethod = function(a,b){
var i = a*b;
return i;
}
function myPrivateMethod(){
var n = this.myPublicMethod(2,3);
}
}
这不起作用。有没有办法在myPrivateMethod中访问myPublicMethod?
答案 0 :(得分:2)
使用this
调用私有方法时,您只需指定Function.prototype.call
的值。
myPrivateMethod.call(this);
E.g。
function myClass(){
this.myPublicMethod = function(a,b){
var i = a*b;
return i;
}
function myPrivateMethod(){
var n = this.myPublicMethod(2,3);
}
//calling private method in the *scope* of *this*.
myPrivateMethod.call(this);
}
请注意,拥有真正的私人成员(不是功能)是以不利用原型为代价的。出于这个原因,我更愿意依赖命名约定或文档来识别私有成员,而不是强制实施真正的隐私。这仅适用于非单件对象。
以下示例演示了上述内容。
//Constructors starts by an upper-case letter by convention
var MyClass = (function () {
function MyClass(x) {
this._x = x; //private by convention
}
/*We can enforce true privacy for methods since they can be shared
among all instances. However note that you could also use the same _convention
and put it on the prototype. Remember that private members can only be
tested through a public method and that it cannot be overriden.*/
function myPrivateMethod() {
this.myPublicMethod1();
}
MyClass.prototype = {
constructor: MyClass,
myPublicMethod1: function () {
//do something with this._x
},
myPublicMethod2: function () {
/*Call the private method by specifying the *this* value.
If we do not, *this* will be the *global object* when it will execute.*/
myPrivateMethod.call(this);
}
};
return MyClass;
})();
答案 1 :(得分:1)
你可以尝试这个来打败当地的范围:
function myClass(){
this.myPublicMethod = function(a,b){
var i = a*b;
return i;
}
// Capture the original context of `this` myClass
var self = this;
function myPrivateMethod(){
var n = self.myPublicMethod(2,3);
}
}
我们使用self
来维护对原始this
的引用,即使上下文正在发生变化(因为我们想在私有方法中调用public方法)。
答案 2 :(得分:1)
执行此操作的一种方法是将每个方法定义为私有,并最终将您想要公开的方法公开(myPrivateMethod
即使myPublicMethod
被覆盖,也会引用原始myClass.myPublicMethod
):
function myClass(){
var myPublicMethod = function(a,b){
var i = a*b;
return i;
}
var myPrivateMethod = function (){
var n = myPublicMethod(2,3);
}
this.myPublicMethod = myPublicMethod;
}
答案 3 :(得分:0)
你可以写
var myPublicMethod = this.myPublicMethod = function()...
因此创建了私有和公共实例。
对我来说似乎更干净。
答案 4 :(得分:0)
您可以将公共函数作为参数传递给私有函数,然后调用它。
this.myPublicMethod = function(a,b){
alert(a * b);
}
function myPrivateMethod(publicMethod){
var n = publicMethod(2,3);
}
myPrivateMethod(this.myPublicMethod);
这是一个工作小提琴.. http://jsfiddle.net/rxtB2/3/
答案 5 :(得分:0)
调用call
的替代方法可以是将方法直接附加到myClass
Function对象。
function myClass(){
myClass.myPublicMethod = function(a,b){
var i = a*b;
return i;
}
this.myPublicMethod = myClass.myPublicMethod;
function myPrivateMethod(){
var n = myClass.myPublicMethod(2,3);
return n;
}
console.log("Calling myPrivateMethod()");
console.log(myPrivateMethod());
}
答案 6 :(得分:0)
如果您只想要“私有”方法,那么您定义它的模式是错误的。我认为可以访问“私有”方法的方法称为特权方法,但可能是错误的。
创建它们的模式如下(在示例中添加了实例变量和继承):
// 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([]);