2

I am new to this so I'll try to be as detailed as possible.

I am creating a JS class using functions.

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

When it comes to methods, I just declare them like this:

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
}

and that's pretty much it.

The problem now is that, when I am creating a specific method:

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

with the method IAmove being declared as follows:

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;
   ...
} 

The compiler just keeps throwing this error:

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

So, the thing is that I am declaring moveFunc as a function but then when I try to get to use this property, it doesn't actually use the instance of the class above it, (Bandstar), but of itself (and obviously moveFunc doesn't have a method called IAmove, the class on which it is being created is)...

I thought this was just like it worked, but I must not be getting the concept of heritage and class morphology in JS right.

How can I access a method in a class from another method inside that same class? If I just write IAmove(p) it will just say the method IAmove() is undefined (because it isn't, it's part of the Bandstar namespace.

I know it must be something stupid that I'm not seeing. Any suggestions?

4

3 回答 3

3

The context inside your function may change based on your call. So this could not be the original object.

You should add a private var like:

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

and use it when you try to call function (or get properties) of original object

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

for be sure to point to original object.

EDIT: According with comments you can read more infos in Stuart's answer

于 2013-01-04T09:48:42.587 回答
1

Assuming all of those methods are defined in the constructor the syntax is correct. The following fiddle illustrates it working, the code is based on a simplified version of your code...

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"});

The cause of the issues is likely to be one of two three things:

  1. How the method moveFunc is called
  2. When the method moveFunc is called
  3. How the method IAmove is called (it may not be the moveFunc function that is causing that error).

The this keyword will reference the scope of the function which is typically the owner of the method...

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

The only reasons that might not be the case is if you are explicitly binding the moveFunc function to another object or a more common situation is that the function is being called without being attached to the owner...

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

The this keyword will default to window if the owner is detached from it. You can bind the function using.

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

In the second issue both methods must be defined in the constructor before the moveFunc function can be called

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

You can log the this object using console.log(this); to find out what it is.

It looks as though from your error that you are trying to call IAmove on the moveFunc function. For this error to be caused you would need to have called moveFunc with itself as the owner or the bound object... Which is not a particularly likely.

I have a hunch that the error may not actually be related to the this.IAmove(p); call in the moveFunc as assumed. Post the stack trace and we can use that to find where the error occurred.

于 2013-01-04T09:56:04.970 回答
1

You probably wants to add these methods to your Bandstar prototype.

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

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

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

This way your methods keep the Bandstar context, and this will remain Bandstar instance reference.

Have a look at Object.prototype reference

于 2013-01-04T09:56:32.317 回答