Object, vreemd gedrag variabelen

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • SvMp
  • Registratie: September 2000
  • Niet online
Ik heb enkele objecten gemaakt volgens dit principe: http://www.wait-till-i.co...l-something-to-the-world/

Ik heb te maken met vreemde bugs, en nader onderzoek wijst uit dat dit bij de variabelen zit.
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
<html><body><script>

var testding = function(){

   var testvar=100;

  function set() {
     this.testvar=12;
  }

  function test() {
     alert('testvar=' + testvar + ' this.testvar=' + this.testvar);
  }

  // reveal all things private by assigning public pointers
  return {
test:test,
set:set,
testvar:testvar
  }
}();

alert(testding.testvar);
testding.test();
testding.set();
testding.test();
alert(testding.testvar);
</script></body></html>


De output is alg volgt:
100
testvar=100 this.testvar=100
testvar=100 this.testvar=12
12

Er zijn dus twee versies van testvar en dat vind ik vreemd.
Want this.testvar verwijst toch naar de in het begin gedeclareerde testvar? Dit levert uiteraard vreemde bugs op als je het niet door hebt.
Maar hoe krijg ik in dit object slechts 1 versie van testvar?

EDIT: Ik heb al een oplossing gevonden.
De 'var varvar=100' er uithalen, en bij de return 'testvar:testvar' vervangen door 'testvar:100'.
Dat werkt. Het script gaat een foutmelding geven omdat je 'testvar' probeert te lezen die niet meer bestaat. Vergissingen worden daardoor niet meer gemaakt, en de foutmeldingen zorgen ervoor dat je alles netjes via this.testvar gaat doen. Maar is dit goed? Ik vind het zo'n vreemde constructie om via die dubbele punt naar een constante te verwijzen?

[ Voor 18% gewijzigd door SvMp op 28-01-2010 12:11 ]


Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 00:12

crisp

Devver

Pixelated

this.testvar is een referentie naar de property van het geretourneerde object, testvar is een referentie naar de variabele die je declareert binnen de anonieme functie die uiteindelijk het object retourneert; een zogenaamde 'closure' dus. Het klopt dus inderdaad dat deze twee niet hetzelfde zijn.
Ik vind het zo'n vreemde constructie om via die dubbele punt naar een constante te verwijzen?
Nee hoor, dat is de normale syntax om properties van een object-literal van waarden te voorzien ;)

[ Voor 25% gewijzigd door crisp op 28-01-2010 13:29 ]

Intentionally left blank


Acties:
  • 0 Henk 'm!

Verwijderd

crisp schreef op donderdag 28 januari 2010 @ 13:27:
this.testvar is een referentie naar de property van het geretourneerde object, testvar is een referentie naar de variabele die je declareert binnen de anonieme functie die uiteindelijk het object retourneert; een zogenaamde 'closure' dus. Het klopt dus inderdaad dat deze twee niet hetzelfde zijn.
Het verwarrende is hier dat ze initeel wel dezelfde waarde hebben vanwege de testvar: testvar op regel 19. Nog verwarrender is het dat het volgens mij wel zou werken als testvar een Object of Array zou zijn omdat die by reference worden doorgegeven en niet by value.

Ik gebruik deze constructies ook wel in mijn code maar dan expliciet alleen om constants (in UPPERCASE) public te maken. Anders maak ik getters en setters.

Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 00:12

crisp

Devver

Pixelated

Blues: dat klopt:
JavaScript:
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
var testding = function(){

    var testvar={foo:100};

    function set() {
        this.testvar.foo=12;
    }

    function test() {
        alert('testvar=' + testvar.foo + ' this.testvar=' + this.testvar.foo);
    }

    // reveal all things private by assigning public pointers
    return {
        test:test,
        set:set,
        testvar:testvar
    }
}();

alert(testding.testvar.foo);
testding.test();
testding.set();
testding.test();
alert(testding.testvar.foo);

Het is dus inderdaad een by reference versus by value probleem; this.testvar is een copy, geen referentie in het geval van topicstarter

[ Voor 5% gewijzigd door crisp op 28-01-2010 16:05 ]

Intentionally left blank


Acties:
  • 0 Henk 'm!

  • Anno
  • Registratie: Augustus 2009
  • Laatst online: 15-09 15:40

Anno

Griefmaker#2862

Moet het onderstaande.

JavaScript:
1
2
var testding = function(){
    var testvar={foo:100};


Niet zijn.

JavaScript:
1
2
var testding = function(){
    this.testvar={foo:100};

Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 00:12

crisp

Devver

Pixelated

AnnoHoekstra schreef op donderdag 28 januari 2010 @ 16:11:
Moet het onderstaande.

[...]

Niet zijn.

[...]
Nee, dan maak je een variabele 'testvar' aan in de global namespace ;)

Voor de duidelijkheid: module pattern is iets anders dan werken met een constructor en instances

[ Voor 16% gewijzigd door crisp op 28-01-2010 16:17 ]

Intentionally left blank


Acties:
  • 0 Henk 'm!

  • Anno
  • Registratie: Augustus 2009
  • Laatst online: 15-09 15:40

Anno

Griefmaker#2862

crisp schreef op donderdag 28 januari 2010 @ 16:16:
Voor de duidelijkheid: module pattern is iets anders dan werken met een constructor en instances
Excuus, ik las alleen de titel van het topic en daarna de code.
Pagina: 1