2010-02-05 3 views
4

Je reçois un "TestFunc n'est pas défini" erreur lorsque ce bit de code ...Javascript: erreur de méthode de prototype?

/* my_object.js */ 
"use strict"; 
function MyObject (param) { 
    this.param = param; 
} 

MyObject.prototype.TestFunc = function() { 
    console.log ('in TestFunc'); 
} 

MyObject.prototype.RealFunc = function() { 
    // I have tried 3 different ways to call TestFunc: 
    // 1. 
    this.TestFunc(); 

    // 2. 
    TestFunc(); 

    // 3. (I didn't really think this would work, 
    //  but thought it was worth a try...) 
    MyObject.TestFunc(); 
} 

... s'exécuté à partir de ce morceau de code:

/* index.js */ 
var myObj = new MyObject ('test'); 
myObj.RealFunc(); // Firebug: "TestFunc is not defined" 
+1

J'ai essayé dans firebug avec seulement 'this.TestFunc()' et deux autres ont commenté, cela fonctionne très bien. Essayez une fois de plus. –

Répondre

3
// 1. 
this.TestFunc(); 

C'est bien. Cela fonctionnera, avec les autres appels supprimés.

(Eh bien, il fonctionne aussi longtemps que vous ne retirez pas le RealFunc de son propriétaire et appelez sur lui-même, comme var method= myObj.RealFunc; method(); ou via un gestionnaire d'événements ou délai d'attente. Dans ce cas this dans RealFunc ne serait pas l'instance MyObject et vous aurez besoin de regarder les fermetures ou Function.bind pour le faire fonctionner.)

// 2. 
TestFunc(); 

Nope, TestFunc n'est pas défini comme une variable portée locale ou globale. Cela provoque l'erreur que vous obtenez de Firebug.

// 3. (I didn't really think this would work, 
//  but thought it was worth a try...) 
MyObject.TestFunc(); 

Non, vous aviez raison. :-) Ce serait MyObject.prototype.TestFunc.call(this), fait explicitement. JavaScript crée un peu la confusion en mettant certaines des mêmes méthodes sur les fonctions de constructeur standard pour les objets intégrés que sur leurs prototypes (par exemple String.split existe où vraiment seulement String.prototype.split devrait). Mais cela n'arrive pas à vos propres objets à moins que vous ne disiez explicitement quelque chose comme MyObject.TextFunc= MyObject.prototype.TextFunc.

+0

ah ah! Je ne l'ai pas inclus dans la version simplifiée ci-dessus, puisque j'ai complètement oublié ce qui arrive à 'this' dans un eventhandler, mais RealFunc() est en effet un gestionnaire d'évènement ... –

+0

Ouais, je m'en doutais ... méthode de liaison de manière et 'ceci' fonctionne dans JavaScript est très étrange par rapport à d'autres langages de programmation; c'est probablement le gotcha le plus commun. – bobince

1

La variante 1 semble correcte. J'ai essayé votre code dans ExecuteJS et a sauté 2. et 3., cela a fonctionné (bien que j'ai enlevé l'appel à console.log et l'ai changé à alert). TestFunc est appelée au sein de RealFunc. Que se passe-t-il si vous enlevez "use strict";?

+0

'use strict' d'ECMAScript Fifth Edition ne fera rien ... encore. J'attends avec impatience que les navigateurs soient publiés là où ils le font, cependant! – bobince

Questions connexes