Votre code est dans l'ordre que vous l'avez cité, n'est-ce pas? Le singleton apparaît au-dessus de RequestManager
dans la source?
Si oui, c'est votre problème. (!) Il est assez subtile, mais en supposant que vos deux bits de code cité sont dans l'ordre que vous avez montré, voici l'ordre dans lequel les choses se passent (je vous expliquerai plus loin):
- La fonction
RequestManager
est défini.
- Votre fonction anonyme qui crée votre singleton s'exécute, y compris l'instanciation d'une instance de
RequestManager
. Le prototype RequestManager
est remplacé par un nouveau prototype.
Depuis l'instance myRequestManager
a été instancié avant le prototype a été changé, il ne possède pas les fonctions que vous avez définies sur ce (nouveau) prototype. Il continue d'utiliser l'objet prototype qui était en place lorsqu'il a été instancié.
Vous pouvez corriger cela facilement en commander à nouveau le code, ou en ajoutant des propriétés RequestManager
« s prototype plutôt que de le remplacer, par exemple:
RequestManager.prototype.require = function(text){
//make an ajax request
};
RequestManager.prototype.otherFunc = function(){
//do other things
};
Cela fonctionne parce que vous n'avez pas remplacé le objet prototype, vous venez d'y ajouter. myRequestManager
voit les ajouts parce que vous les avez ajoutés à l'objet qu'il utilise (plutôt que de définir un nouvel objet sur la propriété prototype
de la fonction constructeur). Pourquoi cela arrive est un peu technique et je vais surtout m'en remettre à la spécification. Lorsque l'interpréteur entre dans un nouveau "contexte d'exécution" (par exemple, une fonction, ou le contexte — par exemple, au niveau de la page —), l'ordre dans lequel il fait les choses n'est pas strict ordre de la source descendante, il y a des phases . L'une des premières phases consiste à instancier toutes les fonctions définies dans le contexte; cela arrive avant tout code étape par étape est exécuté. Détails dans toute leur gloire dans les sections 10.4.1 (code global), 10.4.3 (code de fonction) et 10.5 (liaison de déclaration) dans the spec, mais fondamentalement, les fonctions sont créées avant la première ligne de code étape par étape.:-)
Ceci est plus facile à voir avec un exemple de test isolé:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
<title>Test Page</title>
<style type='text/css'>
body {
font-family: sans-serif;
}
</style>
<script type='text/javascript'>
// Uses Thing1
var User1 = (function() {
var thing1 = new Thing1();
function useIt() {
alert(thing1.foo());
}
return useIt;
})();
// Uses Thing2
var User2 = (function() {
var thing2 = new Thing2();
function useIt() {
alert(thing2.foo());
}
return useIt;
})();
// Thing1 gets its prototype *replaced*
function Thing1() {
this.name = "Thing1";
}
Thing1.prototype = {
foo: function() {
return this.name;
}
};
// Thing2 gets its prototype *augmented*
function Thing2() {
this.name = "Thing2";
}
Thing2.prototype.foo = function() {
return this.name;
};
// Set up to use them
window.onload = function() {
document.getElementById('btnGo').onclick = go;
}
// Test!
function go() {
alert("About to use User1");
try
{
User1();
}
catch (e)
{
alert("Error with User1: " + (e.message ? e.message : String(e)));
}
alert("About to use User2");
try
{
User2();
}
catch (e)
{
alert("Error with User2: " + (e.message ? e.message : String(e)));
}
}
</script>
</head>
<body><div>
<div id='log'></div>
<input type='button' id='btnGo' value='Go'>
</div></body>
</html>
Comme vous pouvez le voir si vous l'exécutez, User1
échoue parce que l'instance Thing1
qu'il utilise ne dispose pas d'une propriété foo
(parce que le prototype a été remplacé), mais User2
fonctionne parce que l'instance Thing2
qu'il utilise * fait (parce que le prototype a été augmenté, non remplacé).
Je n'ai pas reçu l'erreur ... D'où viennent les 'params' lorsque vous construisez le RequestManager? –
Dans l'exemple de code que vous donnez, params n'est défini nulle part. Avez-vous laissé quelque chose hors de votre exemple? – Robusto