从Javascript构造函数调用成员函数

从Javascript构造函数调用成员函数,javascript,Javascript,我遇到了以下问题,这让我很困惑: 我有 function SystemList(UID) { this.refreshData(); } SystemList.prototype.refreshData = function() { this.systemDataObj({}, $.proxy(this.readSuccess, this)); } 当我尝试运行此函数时,会出现以下错误:uncaughttypeerror:Object#在构造函数中没有“refreshData”方法

我遇到了以下问题,这让我很困惑:

我有

function SystemList(UID)
{
  this.refreshData();
}

SystemList.prototype.refreshData = function()
{
  this.systemDataObj({}, $.proxy(this.readSuccess, this));
}
当我尝试运行此函数时,会出现以下错误:uncaughttypeerror:Object#在构造函数中没有“refreshData”方法

有人知道为什么会失败吗?在我看来,它应该能工作

编辑:

我如何创建实例的示例:

function UserMiniProfile(UID)
{
  this.UID = UID;
  this.systemList = new SystemList(this.UID);
  this.htmlID = 'user-'+this.UID+'-profile';
}
var obj = new Thingy("Fred");

function Thingy(name) {
    this.setName(name);
}

Thingy.prototype.setName = function(name) {
    this.name = name;
};

您需要首先分配您的班级:

SystemList = function(UID)
{
  this.refreshData();
}

SystemList.prototype.refreshData = function()
{
  this.systemDataObj({}, $.proxy(this.readSuccess, this));
}

我认为您可能遇到了函数声明与分步代码(规范称之为语句代码)如何以及何时发生的问题

这样的代码将以您描述的方式失败,例如:

function UserMiniProfile(UID)
{
  this.UID = UID;
  this.systemList = new SystemList(this.UID);
  this.htmlID = 'user-'+this.UID+'-profile';
}
var obj = new Thingy("Fred");

function Thingy(name) {
    this.setName(name);
}

Thingy.prototype.setName = function(name) {
    this.name = name;
};
…因为您在将
setName
函数添加到原型之前调用构造函数。请注意,在声明之前调用构造函数很好,这只是因为构造函数使用的是稍后由语句代码设置的函数,所以存在问题。JavaScript解释器尝试处理该代码的顺序是:

  • 创建函数
    Thingy
    ,并使其可用于范围
  • 执行
    var obj=..
    行,调用构造函数
  • 执行构造函数的代码(在本例中抛出异常,因为没有
    this.setName
    函数)
  • 执行
    Thingy.prototype.setName=…
    行。(即,如果在最后一步中没有引发异常。)
  • 这些步骤发生在每个脚本块上(首先完成函数声明,然后按顺序执行语句代码),尽管上面的示例非常明显,但当您开始将来自不同位置的片段组合在一起时,您可以不太明显地创建这种情况

    显然,解决方案是在设置
    setName
    属性之前,确保没有构造对象:

    function Thingy(name) {
        this.setName(name);
    }
    
    Thingy.prototype.setName = function(name) {
        this.name = name;
    };
    
    var obj = new Thingy("Fred");
    
    …同样,上述情况是相当明显的,但在现实世界中,有可能造成这些不太明显的情况

    我怀疑你的情况就是这样。很容易证明:使用Firefox上的Firebug、VS.Net或IE上的脚本调试器、Chrome的DevTools等调试器,在
    SystemList.prototype.refreshData=…
    行上放置一个断点,在执行
    新系统列表(…)
    的行上放置一个断点,然后查看哪个断点先执行


    这里有几个小提琴演示了这个问题:构造函数失败,成功。

    真的吗?我从未见过这种指定js类的方法。不,将其从
    函数系统列表(UID)
    更改为
    系统列表=函数(UID)
    与此无关。它所做的只是将它从一个命名函数更改为一个匿名函数。(引用我自己的话)“它所做的只是将它从一个命名函数更改为一个匿名函数。”事实上,这并不是它所做的全部。它还将其从函数声明更改为函数表达式,这将在以后发生。如果我对OP的代码所做的事情是正确的,那么此更改的可能结果将是,对构造函数的调用将失败,而不是构造函数失败,因为
    SystemList
    将是未定义的。这两种方法都不能解决问题,但我之前的陈述不完整,所以我想我应该标记它。添加了一个我如何创建obj的示例。你确定在扩展其原型后使用的是
    SystemList
    构造函数吗?对我有效:对于登陆此页面的人,如果您忘记了
    new
    ,您将面临类似的错误,因为
    不是您的对象,而是其他对象。也许只是我犯了一个愚蠢的错误…抱歉耽搁了,是的,这就是问题所在。我把东西搬来搬去,现在可以用了。