从javascript类中的“私有”方法访问“公共”方法

时间:2010-04-24 07:13:57

标签: javascript oop private public

有没有办法从类中的“私有”函数调用“公共”javascript函数?

查看下面的课程:

function Class()
{
    this.publicMethod = function()
    {
        alert("hello");
    }

    privateMethod = function()
    {
        publicMethod();
    }

    this.test = function()
    {
        privateMethod();
    }
}

这是我运行的代码:

var class = new Class();
class.test();

Firebug发出此错误:

未定义publicMethod:[中断此错误] publicMethod();

是否有其他方法可以在privateMethod()中调用publicMethod()而无需访问全局类变量[即class.publicMethod()]

4 个答案:

答案 0 :(得分:8)

您可以在构造函数的范围内保存变量以保存对this的引用。

请注意:在您的示例中,在var privateMethod = function()全局privateMethod之前,您遗漏了function Class() { // store this for later. var self = this; this.publicMethod = function() { alert("hello"); } var privateMethod = function() { // call the method on the version we saved in the constructor self.publicMethod(); } this.test = function() { privateMethod(); } } 。我在这里更新了解决方案:

{{1}}

答案 1 :(得分:5)

接受的答案可能会产生不良副作用,即在每个实例中都会创建publicMethodtestprivateMethod的单独副本。避免这种情况的成语是:

function Class()
{}

Class.prototype=(function()
{
    var privateMethod = function(self)
    {
        self.publicMethod();
    }


    return 
    {
        publicMethod: function()
        {
            alert("hello");
        },
        test: function()
        {
            privateMethod(this);
        }
    };
}());

换句话说,您需要将this作为参数传递给私有函数。作为回报,您将获得 true 原型,而无需使用自己的私有和公共函数版本污染每个实例。

答案 2 :(得分:2)

torazaburo的答案是最好的答案,因为它避免了私人成员的多个副本的创建。我很惊讶Crockford根本没有提到它。或者,根据您希望声明公共成员函数的语法,您可以这样做:

function Class()
{}

(function() {
    var privateMethod = function(self) {
        self.publicMethod();
    };

    Class.prototype.publicMethod = function() {
        alert('hello');
    };

    Class.prototype.test = function() {
        privateMethod(this);
    };
}());

答案 3 :(得分:0)

这种做法不是明智之举吗?我不确定

var klass = function(){
  var privateMethod = function(){
    this.publicMethod1();
  }.bind(this);

  this.publicMethod1 = function(){
    console.log("public method called through private method");
  }

  this.publicMethod2 = function(){
    privateMethod();
  }
}

var klassObj = new klass();
klassObj.publicMethod2();