简体   繁体   English

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

[英]Calling member function from Javascript constructor

I am running into the following issue which has really got me stumped: 我遇到了以下问题,这让我很难过:

I have 我有

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

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

When I try and run this, I get the following error: Uncaught TypeError: Object # has no method 'refreshData' within the constructor. 当我尝试运行它时,我收到以下错误:Uncaught TypeError:Object#在构造函数中没有方法'refreshData'。

Anyone have an idea why this is failing? 任何人都知道为什么会失败? To my eye it looks like it should be working. 在我看来它看起来应该是有效的。

Edit: 编辑:

Example of how I create an instance: 我如何创建实例的示例:

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

I think you're probably running into the issue of how and when function declarations vs. step-by-step code (what the spec calls statement code ) happen. 我想你可能会遇到如何以及何时发生函数声明与逐步代码(规范调用语句代码 )的问题。

Code like this will fail in the way you describe, for instance: 像这样的代码将以您描述的方式失败,例如:

var obj = new Thingy("Fred");

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

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

...because you're calling the constructor before adding the setName function to the prototype. ...因为您在将setName函数添加到原型之前调用构造函数。 Note that calling the constructor before its declaration is just fine, it's just because the constructor is using a function that's set up later by the statement code that there's a problem. 请注意,在声明之前调用构造函数就好了,这只是因为构造函数正在使用稍后由语句代码设置的函数,即存在问题。 The order in which the JavaScript interpreter will try to process that code is: JavaScript解释器尝试处理该代码的顺序是:

  1. Create the function Thingy and make it available to the scope. 创建函数Thingy并使其可用于范围。
  2. Execute the var obj = .... line, calling the constructor. 执行var obj = .... line,调用构造函数。
  3. Execute the constructor's code (which in this case throws an exception because there's no this.setName function). 执行构造函数的代码(在这种情况下抛出异常,因为没有this.setName函数)。
  4. Execute the Thingy.prototype.setName = ... line. 执行Thingy.prototype.setName = ...行。 (If no exception had been thrown in the last step, that is.) (如果在最后一步没有抛出任何异常,那就是。)

These steps happen for each script block (first the function declarations are done, then the statement code is executed in order), and even though the above example is fairly obvious, when you start putting together pieces from various different locations, you can create this situation less obviously. 这些步骤发生在每个脚本块中(首先完成函数声明,然后按顺序执行语句代码),即使上面的例子非常明显,当你开始将各个不同位置的片段放在一起时,你可以创建这个情况不太明显。

The solution, obviously, is to make sure you're not constructing the object before you've set up the setName property: 显然,解决方案是确保在设置setName属性之前不构造对象:

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

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

var obj = new Thingy("Fred");

...and again, the above is fairly obvious, but it's possible to create these situations rather less obviously in the real world. ......而且,上述情况相当明显,但在现实世界中创造这些情况的可能性相对较小。

My suspicion is that this is what's happening in your case. 我怀疑这就是你的情况。 It's easy to prove: Using a debugger like Firebug on Firefox, VS.Net or the Script Debugger for IE, Chrome's DevTools, etc., put a breakpoint on the SystemList.prototype.refreshData = ... line and a breakpoint on the line where you're doing your new SystemList(...) and see which one executes first. 很容易证明:在Firefox,VS.Net或IE的脚本调试器,Chrome的DevTools等上使用类似Firebug的调试器,在SystemList.prototype.refreshData = ...行上设置断点并在该行上设置断点你正在做new SystemList(...)并查看哪一个先执行。

Here are a couple of fiddles demonstrating the issue: This one fails in the constructor, this one succeeeds. 这里有一些小问题证明了这个问题: 这个问题在构造函数中失败了, 这个问题成功了。

You need to assign your class first: 您需要先分配您的课程:

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM