Toon posts:

[JS] Fout in recursieve functie

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik ben bezig met een menu, maar er zit ergens een fout in mijn code, maar ik heb geen idee waar...

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
// Variables
var Elements = new Array ();

// Constants
var PROP_ID = 0;
var PROP_HNAME = 1;
var PROP_HREF = 2;
var PROP_TYPE = 3;
var PROP_CHILDS = 4;
var PROP_STATUS = 5;
var TYPE_ROOT = 1;
var TYPE_NODE = 2;
var TYPE_LEAF = 3;
var STAT_OPEN = 0;
var STAT_CLOSED = 1;

// Function to add items to the tree
function AddItem (Id, Hname, Href, Parent, Type)
{
    // Browser check
    if (document.all)
    {
        // Get parent item
        var Parent = GetItem (Elements, Parent);
        // Check if parent is an object
        if (Parent)
        {
            // Check if parent has childs
            if (!Parent [PROP_CHILDS])
                Parent [PROP_CHILDS] = new Array ();

            // Set new child
            var Index = Parent [PROP_CHILDS].length;
            Parent [PROP_CHILDS][Index] = new Array ();
            Parent [PROP_CHILDS][Index][PROP_ID] = Id;
            Parent [PROP_CHILDS][Index][PROP_HNAME] = Hname;
            Parent [PROP_CHILDS][Index][PROP_HREF] = Href;
            Parent [PROP_CHILDS][Index][PROP_TYPE] = Type;
            Parent [PROP_CHILDS][Index][PROP_STATUS] = STAT_OPEN;
        }
        else
        {
            // Check if added item should be root
            if (Type == TYPE_ROOT)
            {
                // Check if root already exists
                if (Elements.length == 0)
                {
                    // Set root
                    var Index = Elements.length;
                    Elements [Index] = new Array ();
                    Elements [Index][PROP_ID] = Id;
                    Elements [Index][PROP_HNAME] = Hname;
                    Elements [Index][PROP_HREF] = Href;
                    Elements [Index][PROP_TYPE] = Type;
                    Elements [Index][PROP_STATUS] = STAT_OPEN;
                }
                else
                {
                    alert ("Root already exists!");
                }
            }
            else
            {
                alert ("Spelling error in your AddItem code!");
            }
        }
    }
}

// Function to get items from tree array
function GetItem (Obj, Id)
{
    // Browser check
    if (document.all)
    {
        // Search all items
        for (Index = 0; Index < Obj.length; Index++)
        {
alert (Index);
            // Check if current object is requested object
            if (Obj [Index][PROP_ID] == Id)
                return Obj [Index];
            else
            {
                // Check if current object has childs
                if (Obj [Index][PROP_CHILDS])
                {
                    // Recursive search
                    var Child = GetItem (Obj [Index][PROP_CHILDS], Id);
                    if (Child)
                        return Child;
                }
            }
        }
    }
    return undefined;
}

// Function to initialize the tree
function InitTree ()
{
    // AddItem (Id, Hname, Href, Parent, Type);
    AddItem ('Root', 'RootHname', 'RootHref', '', TYPE_ROOT);
    AddItem ('Home', 'HomeHname', 'HomeHref', 'Root', TYPE_NODE);
    AddItem ('Algemeen', 'AlgHname', 'AlgHref', 'Home', TYPE_LEAF);
    AddItem ('Disclaimer','DisHname', 'DisHref', 'Home', TYPE_LEAF);
    AddItem ('Credits', 'CreditsHname', 'CreditsHref', 'Home', TYPE_LEAF);

    AddItem ('Admin', 'AdminHname', 'AdminHref', 'Root', TYPE_NODE);
    AddItem ('Medewerker', 'MedHname','MedHref', 'Admin', TYPE_LEAF);

    DrawTree ();
}


Zoals je ziet zitten er momenteel een aantal alerts in. Die alert (Index) geeft de hele tijd alleen maar nullen, dus het lijkt wel alsof die for loop gewoon niet doorlopen wordt.

De DrawTree functie (niet bijgevoegd) werkt gewoon goed, kan niet missen. Het gaat fout bij het invoegen van de data aan de array. Zodra ik meerdere items invoeg met parent Root dan krijg ik de volgende melding: Spelling error in your AddItem code!
Daaruit blijkt dat het bij GetItem functie fout gaat.

Enige hulp zou welkom zijn, wat doe ik fout en suggesties zijn altijd welkom.

Alvast bedankt.

Verwijderd

for(var Index ...

Verwijderd

Topicstarter
Hrmmmm, dat zo'n klein iets zo'n probleem kan veroorzaken.

Ach, het werkt, weer iets geleerd.

Bedankt!!!!

Toch nog een vraagje erover:

Dit gaat gewoon goed:
code:
1
2
for (testvar = 0; testvar < 10; testvar++)
    alert ("testvar = " + testvar);


Maar in mijn code ging het schijnbaar niet goed, komt dat doordat je met recursieve functies werkt en dat daardoor de variabele somehow verneukt werd?

  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 13:27
Het wordt met var een lokale variable...

Verwijderd

Stel je wilt een rij krijgen als dit:

1 - 2 - 3 -
1 - 2 - 3 -
1 - 3 - 3 -

Dan zou je denken dat onderstaand voorbeeld werkt. Nou mooi niet dus. Dat komt omdat de for-loop in de functie echoRow(); variabele i weer op 0 zet. Omdat je niet het keyword "var" gebruikt hebt, zet hij de globale variabele i weer op 0. Maar die variabele wordt al gebruikt om 4 rijen af te drukken.
Misschien moet je eens iets lezen over het bereik van variabelen. "scope"

code:
1
2
3
4
5
6
7
8
9
10
11
12
var i;

function echoRow() {
  var sRet = '';  
  for (i = 0; i < 4; i++) {
    sRet += i + " - ";
  }
}

for (i = 0; i < 4; i++) {
  echoRow();
}

Verwijderd

Topicstarter
Tja, jij maakt er een globale variabele van door hem bovenin te declareren, maar dat was bij mij niet het geval ;)

Ik had dus echt niet verwacht dat het een globale variabele zou worden als je hem niet declareert....

Het lijkt me overigens dat als ik hem al als globale variabele had gedeclareert, dat ik een error zou krijgen dat de variabele als gedeclareert is nadat ik natuurlijk de var in de for loops had gezet.

Maar goed, topic kan op slot...geloof niet dat er nog nuttige posts komen :)

  • André
  • Registratie: Maart 2002
  • Laatst online: 00:33

André

Analytics dude

Daarom in for-loops altijd var gebruiken:

code:
1
for (var i = ...

Verwijderd

Nee, altijd weten waar je mee bezig bent. Soms wil je juist dat een variabele in een for-loop in een functie globaal gemaakt wordt.

Je moet gewoon weten wat het bereik van variabelen is.

Dat ik de globale variabele in mijn voorbeeld expliciet declareer, maakt niets uit. Zonder die declaratie gaat het ook fout.

In JS is een variabele altijd globaal, tenzij je hem expliciet declareert met var:

code:
1
2
3
4
5
6
7
8
9
10
11
12
var i = 0;
var b = 1;
function foo() {
  i = 1;
  a = 2;
  var b = 2;
}
foo();

alert(i);
alert(a);
alert(b);


Draai dat voorbeeldje en het zal je duidelijk worden (als het je nog niet duidelijk is)

Verwijderd

Verwijderd schreef op 24 mei 2004 @ 13:31:
Ik had dus echt niet verwacht dat het een globale variabele zou worden als je hem niet declareert....
In JavaScript is elke variabele die zonder var wordt gedeclareert automatisch globaal.
Het lijkt me overigens dat als ik hem al als globale variabele had gedeclareert, dat ik een error zou krijgen dat de variabele als gedeclareert is nadat ik natuurlijk de var in de for loops had gezet.
Nee, dat is niet waar:
Java:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
var s = "Ik ben globaal";

function dosomething() {

    // Gedeclareerd met 'var', dus lokaal
    // Een globale variabele met dezelfde
    // naam blijft intact 

    var s = "ik ben lokaal";
}

function dosomething2() {

    // Gedeclareerd zonder 'var' dus globaal
    // Omdat er al een globale variabele is
    // met deze naam wordt die overschreven

    s = "ik ben niet lokaal";
}

alert(s);   // "Ik ben globaal"

dosomething();
alert(s);   // "Ik ben globaal"

dosomething2();
alert(s);   // "Ik ben niet lokaal"

Is dat een beetje duidelijk?
Pagina: 1