12

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

查看以下课程:

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

    privateMethod = function()
    {
        publicMethod();
    }

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

这是我运行的代码:

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

Firebug 给出了这个错误:

publicMethod 未定义:[Break on this error] publicMethod();

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

4

4 回答 4

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();
  }
}
于 2010-04-24T07:18:04.070 回答
5

接受的答案可能具有不受欢迎的副作用,即在每个实例中都会创建publicMethodtest和的单独副本。privateMethod避免这种情况的习惯用法是:

function Class()
{}

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


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

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

于 2013-06-17T04:15:20.043 回答
2

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

function Class()
{}

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

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

    Class.prototype.test = function() {
        privateMethod(this);
    };
}());
于 2013-07-31T19:44:12.220 回答
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();
于 2014-04-02T07:25:31.833 回答