我是新手,所以我会尽量做到尽可能详细。
我正在使用函数创建一个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命名空间的一部分。
我知道这一定是愚蠢的,我没有看到。有什么建议吗?
答案 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 三件事之一:
moveFunc
moveFunc
时IAmove
(它可能不是导致该错误的moveFunc
函数)。 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实例参考。