server info
server info

Reputation: 1335

How to reference a object method in another object method

I have a basic lack in understanding the OOP for javascript. What I understand is that I can make classes like this

var Car = function(){}

Car.prototype.GetBrand = function(){ return "Ford";}
Car.prototype.GetYear = function(){ return "1989";}

var ford = new Car();

ford.GetBrand();
ford.GetYear();

this works... Now I want to implement a function GetInfo and this should print out Brand & Date

how can I reference the GetBrand() and GetYear() methods in my GetInfo() method.

  This is not working:
Car.prototype.GetInfo = function(){ 
        return this.GetBrand()+ ' '+ this.GetYear();
    }

this is not the right accessor... What do I miss here?

OK edit: this was a simplified example there my realy method call is in anothe function and that's why we are talking about another scope:

JsonLoader.prototype.GetJsonAndMerge = function(url,template,tagToAppend){
$.ajax({
    url: url,
    dataType: 'json',
    success: function(data) {
        this.ShowItems(data,template,tagToAppend); 
        }
    });
}

I try to reach my ShowItems method... here and this is again in a function that's maybe why the this operator does not work... sorry for the confusion =/

Upvotes: 0

Views: 318

Answers (4)

Quentin
Quentin

Reputation: 944427

this is context sensitive to how the function it is in is called.

You are trying to use this from when foo.GetJsonAndMerge is called, but you aren't using it in GetJsonAndMerge. You are using it in an anonymous function which is called by $.ajax.

You need to make a copy of the current value of this in a variable that will remain available to the anonymous function when it gets called.

JsonLoader.prototype.GetJsonAndMerge = function(url,template,tagToAppend){
    var that = this; // COPY THIS
    $.ajax({
        url: url,
        dataType: 'json',
        success: function(data) {
            // USE THE COPY YOU PLACED IN THAT INSTEAD OF THIS
            that.ShowItems(data,template,tagToAppend); 
        }
    });
}

Upvotes: 0

Tomalak
Tomalak

Reputation: 338406

You are missing an unintended recursion:

Car.prototype.GetInfo = function (){  
  return this.GetBrand()+ ' '+ this.GetYear(); // instead of GetInfo() !
}

Then you can call

ford.GetInfo() // returns "Ford 1989"

EDIT: The reason to use prototype here is to conserve memory. When you call new Car(), the object gets copied, not "constructed" in the traditional sense. Calling new on

var Car = function(){
  this.GetBrand = function(){ return "Ford";}
  this.GetYear = function(){ return "1989";}
}

would also copy the function bodies to every instance. This is why putting a method into the prototype chain makes sense. Also adding a function to already-existing instances only works when adding it to the prototype chain.

Also note that the convention is to give capital first letters to constructor functions only, so Car is okay, but GetInfo should be getInfo.


JsonLoader.prototype.GetJsonAndMerge = function(url,template,tagToAppend){
  var self = this;
  $.ajax({
    url: url,
    dataType: 'json',
    success: function(data) {
      self.ShowItems(data,template,tagToAppend); 
      }
    });
  }
}

Upvotes: 2

Quentin
Quentin

Reputation: 944427

You are calling GetInfo recursively.

You probably mean:

return this.GetBrand()+ ' '+ this.GetYear();
//                                   ^^^^

Which works fine.

Upvotes: 0

Thomas Shields
Thomas Shields

Reputation: 8943

You're calling GetInfo from inside its definition; naturally that's not going to work:

Car.prototype.GetInfo = function(){ 
        return this.GetBrand()+ ' '+ this.GetInfo(); //note GetInfo here
    }

I believe you want:

Car.prototype.GetInfo = function(){ 
            return this.GetBrand()+ ' '+ this.GetYear(); //note GetYear here
        }

...then just call it with ford.GetInfo()

Upvotes: 1

Related Questions