2011-05-28 4 views
0

J'ai un manque fondamental dans la compréhension de la POO pour javascript. Ce que je comprends est que je peux faire des cours comme celui-ciComment référencer une méthode d'objet dans une autre méthode d'objet

var Car = function(){} 

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

var ford = new Car(); 

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

cela fonctionne ... Maintenant, je veux mettre en œuvre une fonction GetInfo et cela devrait imprimer Marque & Date de

comment puis-je faire référence à la GetBrand() et méthodes GetYear() dans ma méthode GetInfo().

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

ce n'est pas le manipulateur droit ... Que manque ici?

modifier OK: c'est un exemple simplifié là ma méthode realy appel est en anothe fonction et c'est la raison pour laquelle nous parlons d'une autre portée:

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

je cherche à atteindre ma méthode ShowItems ... ici et cela est à nouveau dans une fonction qui est peut-être la raison pour laquelle le cet opérateur ne fonctionne pas ... désolé pour la confusion =/

+0

bien à quoi sert votre méthode ShowItems? et pourquoi essayez-vous de l'atteindre avec "ceci"? –

+0

Wowzers. C'est un problème complètement différent. Une bonne leçon pour savoir pourquoi vous devriez tester vos cas de test réduits pour vous assurer qu'ils montrent toujours le même problème (avec les mêmes messages d'erreur). – Quentin

+0

@Thomas Shields: ShowItems est aussi (ou devrait être) une méthode membre de JsonLoader, ... JsonLoader.prototype.ShowItems (data, template, tagToAppend) –

Répondre

2

Il vous manque une récursion involontaire:

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

Ensuite, vous pouvez appeler

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

EDIT: La raison d'utiliser prototype ici est de conserver la mémoire. Lorsque vous appelez new Car(), l'objet est copié, pas "construit" dans le sens traditionnel. Appel new sur

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

serait également copier les corps de fonction à chaque instance. C'est pourquoi mettre une méthode dans la chaîne du prototype a du sens. L'ajout d'une fonction à des instances déjà existantes ne fonctionne que lorsque vous l'ajoutez à la chaîne prototype.

Notez également que la convention est de donner premières lettres majuscules seulement aux fonctions de constructeur, donc Car est correct, mais GetInfodevrait êtregetInfo.


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

Merci pour la réponse. Je pourrais avoir un autre problème de portée ... J'ai édité la question. Je devais me soumettre au début ... –

+0

@serverinfo: Oui, voir ma deuxième édition. La signification de 'this' change de contexte en contexte. Si vous souhaitez conserver une certaine signification à travers les appels, vous devez stocker l'actuel 'this' dans une variable temporaire. – Tomalak

+0

merci qui a travaillé ... désolé pour toute la confusion ... =) –

1

Vous appelez GetInfo à l'intérieur de sa définition; naturellement qui ne va pas au travail:

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

Je crois que vous voulez:

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

... alors il suffit d'appeler avec ford.GetInfo()

+0

Oui, j'avais tort de l'éditer. –

0

Vous appelez GetInfo récursive.

Vous voulez dire sans doute:

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

Ce qui fonctionne très bien.

+0

oui merci édité ma question –

0

this est sensible au contexte de l'appel de la fonction dans laquelle elle se trouve.

Vous essayez d'utiliser this à partir de quand foo.GetJsonAndMerge est appelée, mais vous ne l'utilisez pas dans GetJsonAndMerge. Vous l'utilisez dans une fonction anonyme appelée par $.ajax.

Vous devez effectuer une copie de la valeur actuelle de this dans une variable qui restera disponible pour la fonction anonyme lorsqu'elle est appelée.

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); 
     } 
    }); 
} 
Questions connexes