JavaScript: 对象的方法未被识别;为什么不?

JavaScript: Methods for objects are not being recognized; why not?

我正在尝试创建一个会跟随我的鼠标转动的头像。


我已经成功创建了一个可用的头像,现在我想用对象构造函数创建一个相同的头像。基本上一切都是一样的,除了当我输入 var angleToBe; 时我会写 this.angleToBe;。一切都直接链接到构造函数。在使用方法之前,我没有遇到任何问题,特别是 turnToMouse 方法。我的语法如下所示:

Avatar.prototype.turnToMouse = function() {
  if (this.canTurn) {
    this.spotX = this.body.position.x;
    this.spotY = this.body.position.y;
    this.spotY = this.spotY * -1 + height;
    this.body.angleToBe = Math.atan2(cursorX - this.spotX, cursorY - this.spotY);
    this.body.__dirtyRotation = true;
    this.body.__dirtyPosition = true;
    this.gun.__dirtyRotation = true;
    this.gun.__dirtyPosition = true;
    this.body.rotation.set(0, 0, avatarAngleToBe);
  }
  setTimeout(this.turnToMouse, time);
};

阿凡达是构造器

本质上,这个函数只是不断地将头像(和它的枪)转向鼠标的方向。这个函数可以正常工作,因为它与我当前的工作函数完全相同(除了 this 之外)。

我遇到的问题是,当我将此代码放入构造函数(function Avatar() {})时:

this.turnToMouse();

应该是在调用我的函数,编辑认为没有函数'turnToMouse()'。

我错过了什么吗?

PS:如果你想看我现在的工作头像和对象头像的代码,click this link in google chrome.

JavaScript有个概念叫做hoisting。这样做的目的是让某些语句 "hoisted" 到达范围的顶部。

在您的特定情况下,您的 function Avatar(...) { ... } 定义是 提升的 以便在您调用 new Avatar(...) 时可用。如果不是,您的代码就不会走那么远,因为 Avatar 在技术上尚未定义。

然而,您 运行 遇到的问题是,并非所有内容都已提升。您对 Avatar.prototype.turnToMouse 的分配仍然发生 在您调用 new Avatar(...) 之后 这意味着该方法在 运行s![=22= 时尚不存在]

要解决此问题,只需确保 运行 new Avatar(...) 分配了所有 Avatar.prototype 属性之后。


PS。如果您没有在构造函数中调用该方法,那也没关系,因为原型中的属性即使对于在分配之前创建的实例也是可用的,只是在实际分配之前在执行期间不可用。


PPS。关于您的 setTimeout 调用,您将 运行 陷入另一个与 this 绑定的问题。要解决这个问题,只需将其更改为:

var avatar = this;
setTimeout(function () { avatar.turnToMouse(); }, time);

为什么会这样,我会留下另一个答案,但如果您阅读 function binding/context,您可以在线找到资源。