类和模拟中的JS和方法

时间:2013-01-04 09:42:42

标签: javascript html5 oop

我是新手,所以我会尽量做到尽可能详细。

我正在使用函数创建一个JS类。

function Bandstar(p, id)
{
  var numberOfSides, Xcenter, Ycenter;
  var canvas;
  var circlesInt;
  var linesInt;
  var lines;
  var linesInt2;
  var linesMidToEdge; 
.....

说到方法,我只是声明它们:

this.IAset = function(a) 
{
   for (var i =0; i<= this.numberOfSides-1;i++)
   {
      if (parseInt(a[i]) == a[i])
         this.circles[i].value = a[i];
      else
         return false;
    }

    this.IArepaint();
    return true
}

这就是它。

现在的问题是,当我创建一个特定的方法时:

this.moveFunc = function(e)
{
   var p = e.target;
   this.IAmove(p);
};

方法IAmove声明如下:

this.IAmove = function(p)
{
   var m = (p.oTop - this.Ycenter ) / (p.oLeft - this.Xcenter);
   var linea = m * ( p.left - p.oLeft) + p.oTop;
   var ejeX = p.left;
   ...
} 

编译器不断抛出此错误:

Uncaught TypeError: Object function (e)   {     var p = e.target;     this.IAmove(p);   } has no method 'IAmove'

所以,问题是我将moveFunc声明为函数但是当我尝试使用this属性时,它实际上并没有使用它上面的类的实例, (Bandstar),但它本身(显然moveFunc没有名为IAmove的方法,正在创建它的类是... ...

我认为这就像它有效一样,但我不能在JS中获得遗产和类形态的概念。

如何从同一个类中的另一个方法访问类中的方法?如果我只是写IAmove(p),它只会说方法IAmove()未定义(因为它不是,它是Bandstar命名空间的一部分。

我知道这一定是愚蠢的,我没有看到。有什么建议吗?

3 个答案:

答案 0 :(得分:3)

您的功能内容可能会根据您的通话发生变化。所以this不能成为原始对象。

你应该添加一个私有的var:

 function Bandstar(p, id)
{
  var numberOfSides, Xcenter, Ycenter;
  var canvas;
  var that = this; // add this line

并在尝试调用原始对象的函数(或获取属性)时使用它

this.moveFunc = function(e)
  {
    var p = e.target;
    that.IAmove(p); // change this line
  };

确保指向原始对象。

编辑:根据评论,您可以在Stuart's answer

中阅读更多信息

答案 1 :(得分:1)

假设所有这些方法都在构造函数中定义,语法正确。以下fiddle说明了它的工作原理,代码基于代码的简化版本......

function Test() {
    this.move = function(p) {
        document.write("Moved to: " + p);
    };
    this.another = function(e) {
        this.move(e.target);
    };
}

var test = new Test();
test.another({target: "The moon"});

问题的原因很可能是 two 三件事之一:

  1. 如何调用方法moveFunc
  2. 调用方法moveFunc
  3. 如何调用方法IAmove(它可能不是导致该错误的moveFunc函数)。
  4. this关键字将引用函数的范围,该函数通常是方法的所有者...

    var bandstar = new Bandstar(p, id);
    bandstar.moveFunc(e); // this should be bandstar
    

    可能不是这种情况的唯一原因是,如果您将moveFunc函数显式绑定到另一个对象,或者更常见的情况是函数被调用而没有附加到所有者... < / p>

    var bandstar = new Bandstar(p, id);
    var moveFunc = bandstar.moveFunc(e);
    moveFunc(e); // this will now be window
    

    如果所有者与其分离,this关键字将默认为window。您可以使用。

    绑定该功能
    var bandstar = new Bandstar(p, id);
    var moveFunc = bandstar.moveFunc(e);
    moveFunc.bind(bandstar);
    moveFunc(e); // this will now be bandstar again
    

    在第二个问题中,必须在构造函数中定义两个方法才能调用moveFunc函数

    this.moveFunc = function(e) { ... }
    this.moveFunc(e); // Will throw an error that IAmove does not exist in the object
    this.IAmove = function(p) { ... }
    

    您可以使用this记录console.log(this);对象,了解它是什么。

    从错误中看,您试图在IAmove函数上调用moveFunc。要导致此错误,您需要调用moveFunc将其自身作为所有者或绑定对象...这不是特别可能。

    我预感到这个错误实际上可能与假定的this.IAmove(p);中的moveFunc调用无关。 发布堆栈跟踪,我们可以使用它来查找错误发生的位置。

答案 2 :(得分:1)

您可能希望将这些方法添加到您的Bandstar原型

function Bandstar(p, id)
{
   // ...
}

Bandstar.prototype.IAset = function(a) 
{
   // ...
}

Bandstar.prototype.moveFunc = function(e)
{
   var p = e.target;
   this.IAmove(p);
};

这样您的方法就会保留Bandstar上下文,this将保留Bandstar实例参考。

查看Object.prototype reference