[JS/TS] Globale instance bijhouden?

Pagina: 1
Acties:

Onderwerpen

Vraag


Acties:
  • 0 Henk 'm!

  • Carharttguy
  • Registratie: Juli 2010
  • Laatst online: 04-07 23:09
Beste mede-Tweakers

Ik ben vrij nieuw met JavaScript of Typescript, dus waarschijnlijk is dit een simpel op te lossen probleem.
Ik heb 2 files: index.html en editor.js (komt van editor.ts)

In editor.js staat een klasse 'Editor'. Ook staat dit er nog:

code:
1
2
3
4
5
6
7
8
9
10
11
window.addEventListener('DOMContentLoaded', () => {
    // Create the game using the 'renderCanvas'
    var gEditor = new Editor('renderCanvas');

    // Create the scene
    gEditor.createScene();

    // start animation
    gEditor.animate();

});


Dit werkt zonder problemen. In het begin stond er let ipv var. Maar nu wil ik vanuit mijn html file de gEditor instantie kunnen gebruiken. Ik las dat var in JS global is, dus ik dacht dat ik nu zoiets in mijn html zou kunnen zetten:

code:
1
<button onclick="gEditor.test();">testknop</button>


Nou, mooi niet dus natuurlijk.
ReferenceError: gEditor is not defined
Hoe meer global dan global kan ik gaan? Hoe reference ik gEditor in mijn html file?
Ik zou van m'n klasse een singleton kunnen maken, maar ergens lijkt mij dat ik gewoon iets kleins mis.

Hartelijk dank voor de inzichten.

Beste antwoord (via Carharttguy op 11-07-2017 23:15)


  • Caelorum
  • Registratie: April 2005
  • Laatst online: 09:25
Carharttguy schreef op dinsdag 11 juli 2017 @ 20:06:
[...] Ik las dat var in JS global is, dus ik dacht dat ik nu zoiets in mijn html zou kunnen zetten:[...]
Dat is niet geheel waar: https://docs.microsoft.co...variable-scope-javascript
Doordat je de variabele declareert binnen een function is de scope beperkt tot die functie. Wat je kan doen is ipv
JavaScript:
1
 var gEditor = new Editor('renderCanvas');

het bijv. op de window zetten
code:
1
 window.gEditor = new Editor('renderCanvas');

of
JavaScript:
1
2
3
4
 //buiten de functie
var gEditor = null;
//binnen functie
gEditor = new Editor('renderCanvas');

[ Voor 11% gewijzigd door Caelorum op 11-07-2017 20:12 ]

Alle reacties


Acties:
  • Beste antwoord
  • +1 Henk 'm!

  • Caelorum
  • Registratie: April 2005
  • Laatst online: 09:25
Carharttguy schreef op dinsdag 11 juli 2017 @ 20:06:
[...] Ik las dat var in JS global is, dus ik dacht dat ik nu zoiets in mijn html zou kunnen zetten:[...]
Dat is niet geheel waar: https://docs.microsoft.co...variable-scope-javascript
Doordat je de variabele declareert binnen een function is de scope beperkt tot die functie. Wat je kan doen is ipv
JavaScript:
1
 var gEditor = new Editor('renderCanvas');

het bijv. op de window zetten
code:
1
 window.gEditor = new Editor('renderCanvas');

of
JavaScript:
1
2
3
4
 //buiten de functie
var gEditor = null;
//binnen functie
gEditor = new Editor('renderCanvas');

[ Voor 11% gewijzigd door Caelorum op 11-07-2017 20:12 ]


Acties:
  • 0 Henk 'm!

  • johnkeates
  • Registratie: Februari 2008
  • Laatst online: 04-07 16:30
Behalve die opties heb je natuurlijk ook gewoon het singleton pattern waar je het mee kan oplossen als je maar 1 instantie nodig hebt.

Acties:
  • 0 Henk 'm!

  • Klaasvaak
  • Registratie: Maart 2010
  • Laatst online: 23-09 22:25
Het wordt sterk aangeraden HTML en JS gescheiden te houden. Dus inplaats van het onclick attribuut te gebruiken geef je de button een id. Vervolgens haal je die button op in je JS en hang er de eventlistener aan. Hou er ook rekening mee dat die arrowfuncties nieuw zijn en niet in oudere browsers worden ondersteund. Ook is tegenwoordig gebruikelijk om je JS te starten middels een functie aan het einde van je <body> ipv de onload/DOMContentLoaded events te gebruiken.

code:
1
<button id="testButton">testknop</button>

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<script>
(function() {
    // Create the game using the 'renderCanvas'
    var gEditor = new Editor('renderCanvas');

    // Create the scene
    gEditor.createScene();

    // start animation
    gEditor.animate();

    // add listener to button
    document.getElementById('testButton').addEventListener('click', gEditor.test.bind(gEditor));
}());
</script>
</body>
</html>

Acties:
  • 0 Henk 'm!

  • Carharttguy
  • Registratie: Juli 2010
  • Laatst online: 04-07 23:09
Caelorum schreef op dinsdag 11 juli 2017 @ 20:10:
[...]

Dat is niet geheel waar: https://docs.microsoft.co...variable-scope-javascript
Doordat je de variabele declareert binnen een function is de scope beperkt tot die functie. Wat je kan doen is ipv
...
Inderdaad. Ik moet dringend beter lezen zo blijkt. Dank voor de heldere uitleg + meerdere oplossingen!
johnkeates schreef op dinsdag 11 juli 2017 @ 20:12:
Behalve die opties heb je natuurlijk ook gewoon het singleton pattern waar je het mee kan oplossen als je maar 1 instantie nodig hebt.
Klopt, die oplossing had ik ook al aangedragen in de OP. Maar het is op dit moment niet zeker dat deze klasse maar 1 instance zal hebben.
Klaasvaak schreef op dinsdag 11 juli 2017 @ 21:07:
Het wordt sterk aangeraden HTML en JS gescheiden te houden. Dus inplaats van het onclick attribuut te gebruiken geef je de button een id. Vervolgens haal je die button op in je JS en hang er de eventlistener aan. Hou er ook rekening mee dat die arrowfuncties nieuw zijn en niet in oudere browsers worden ondersteund. Ook is tegenwoordig gebruikelijk om je JS te starten middels een functie aan het einde van je <body> ipv de onload/DOMContentLoaded events te gebruiken.
Bedankt voor de opmerkingen. Ik zal inderdaad geen onclick gebruiken. Javascript wordt van buitenaf injected, dus het was meer om de scope te testen.

Interessant, die functie aan het einde van de body ipv onload/DOMContentLoaded. Wat is de reden juist dat dit tegenwoordig meer gangbaar is?

Bedankt iedereen, wederom snel antwoord op een vraag!