Twój kod jest w podanej kolejności, prawda? Singleton pojawia się nad źródłem w RequestManager
?
Jeśli tak, to twój problem. (!) To dość subtelna, ale zakładając, że dwa bity kodu podane są w kolejności Pokazaliśmy im, oto kolejność rzeczy się zdarzają (będę to wyjaśnić więcej poniżej):
- Funkcja
RequestManager
jest zdefiniowany.
- Twoja anonimowa funkcja, która tworzy pojedyncze przebiegi, włącznie z instancją instancji
RequestManager
.
- Prototyp
RequestManager
zostaje zastąpiony nowym.
Ponieważ instancja myRequestManager
została instancja przed prototyp został zmieniony, nie ma funkcje zdefiniowane na tej (nowej) prototypu. W dalszym ciągu używa obiektu prototypowego, który był na miejscu, kiedy został utworzony.
Można to łatwo naprawić przez ponowne zamawianie kod, albo przez dodanie właściwości prototypu RequestManager
„s zamiast zastępując ją np:
RequestManager.prototype.require = function(text){
//make an ajax request
};
RequestManager.prototype.otherFunc = function(){
//do other things
};
To działa, ponieważ nie masz zastąpiony się prototypowy obiekt, właśnie go dodałeś. myRequestManager
widzi dodatki, ponieważ dodałeś je do obiektu, którego używa (zamiast ustawiania nowego obiektu we właściwości funkcji konstruktora: prototype
).
Dlaczego tak się dzieje jest nieco techniczny i przeważnie odroczę do specyfikacji. Kiedy interpreter wprowadza nowy "kontekst wykonania" (np. Funkcję lub globalny kontekst, np. Strona-strona —), kolejność, w jakiej to robi, nie jest ścisłym odgórnym porządkiem źródłowym, są fazy . Jedną z pierwszych faz jest utworzenie wszystkich funkcji zdefiniowanych w kontekście; tak się stanie przed wykonywany jest każdy krok po kroku. Szczegóły w całej ich okazałości w sekcjach 10.4.1 (kod globalny), 10.4.3 (kod funkcji) i 10.5 (powiązaniach deklaracji) w the spec, ale w zasadzie funkcje są tworzone przed pierwszą linią kodu krok po kroku.:-)
to najłatwiej zobaczyć z izolowanym przykładzie testowym:
<!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>
Jak widać, jeśli go uruchomić, User1
powiodło się, ponieważ instancja Thing1
jest za pomocą nie posiada własności foo
(ponieważ prototyp został zastąpiony), ale User2
działa, ponieważ instancja Thing2
używa *, ponieważ prototyp został rozszerzony, a nie zastąpiony.
Nie otrzymałem błędu ... Skąd pochodzą "parametry" podczas konstruowania menedżera RequestManager? –
W przykładowym kodzie, który podajesz, nigdzie nie są zdefiniowane parametry. Czy zostawiłeś coś ze swojego przykładu? – Robusto