Microsoft Windows: A thirty-two bit extension and graphical shell to a sixteen-bit patch to an eight-bit operating system originally coded for a four-bit microprocessor which was written by a two-bit company that can't stand one bit of competition
Ik denk dat je hier wel wat aan hebt:
Functies zijn gewoon objecten in JS. Je kunt ze dus gewoon ook als parameter doorgeven. Je hebt echter ook de mogelijkheid om functies in de context van een bepaald object aan te roepen. Doorgaans doe je dat in de form van obj.func();, die mogelijkheid heb je echter alleen als func in de prototype van de constructor functie van obj voorkomt.
Stel dat obj een object van class ObjClass is. Dan zou dit precies gelijk zijn aan de bovenstaande aanroep: ObjClass.prototype.func.call(obj);. Op deze manier kun je functies ook aanroepen op objecten die deze functie helemaal niet in de prototype hebben staan. Het aanroepen van een bepaalde functie in de context van een object houdt in dat je binnen die functie met this kunt werken, waarbij this dan verwijst naar dat object. Als je een functie echter aanroept buiten de context van een object, dan verwijst this naar iets anders. (Ik weet niet zeker of het gedefineerd is, maar in Firefox verwijst hij dan naar het Window object.)
Dit is ook wat je in bovenstaande code terug ziet. Vooral TestClass.test is belangrijk. Ik roep de functie op 5 verschillende manieren aan. Daarvoor gebruik ik ook een paar hulp functies om aan te tonen hoe het werkt. In het eerste voorbeeld van ik de functie alertValue eerst op in een lokale variabel. Daarna roep ik hem aan, maar niet meer binnen de context van this. Wat er dus gebeurt is dat this binnen alertValue niet meer naar this in test verwijst. In het 2de geval gebeurt precies hetzelfde. Alleen wordt de functie dan als parameter meegegeven aan een andere functie die hem dan weer aanroept.
In voorbeeld 3 gebeurt wat anders. Daar vang ik this eerst op in de lokale variabel self, welke ik later nodig heb in de (anonieme) functie die ik doorgeef aan TestFunc1. TestFunc1 roept de gegeven functie aan die dan weer gebruik van self maakt. Dit is een belangrijk, maar (zeker in het begin) moeilijk concept om te snappen. Het heet closure, wat inhoudt dat een functie aangemaakt in een bepaalde scope zelf ook toegang heeft tot die scope, naast zijn eigen scope. Die omringende scope wordt er dus al het ware bij ingesloten. Hoewel self niet binnen de scope van de anonieme functie valt, heeft deze er wel toegang tot. Echter niet tot this, wat zeker belangrijk te onthouden is, omdat this altijd verwijst naar de context waarin een functie is aangeroepen (of geen).
In voorbeeld 4 roep ik TestFunc2 aan en geef 2 parameters. De eerste is de functie zelf en de 2de het object waarop ik de functie wil aanroepen. Dit zorgt dus dat this binnen alertValue nog steeds naar dezelfde this binnen test verwijst.
Het laatste voorbeeld is typische polymorphisme. TestFunc3 vraagt een object met een bepaalde interface (in dit geval moet functie alertValue geimplementeerd zijn) en roept daaruit een functie aan. Welk object of class het is, is niet belangrijk.
Mijn voorkeur voor jouw probleem gaat uit naar voorbeeld 3. Dit is de gemakkelijkste oplossing. Ik zou zeggen, ga nog eens wat opzoeken over closure en zorg dat je dit concept goed snapt. Het zal je zeker helpen bij het ontwikkelen van JS scripts.
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
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
| function TestClass(value) { this.value = value; } TestClass.prototype.alertValue = function() { alert( 'Object: ' + this + ', Constructor: ' + this.constructor.name + ', Source: ' + this.toSource() + ', Value: ' + this.value ); }; TestClass.prototype.test = function() { // voorbeeld 1 var func = this.alertValue; func(); // voorbeeld 2 TestFunc1(this.alertValue); // voorbeeld 3 var self = this; TestFunc1( function() // anonieme functie { self.alertValue(); } ); // voorbeeld 4 TestFunc2(this.alertValue, this); // voorbeeld 5 TestFunc3(this); }; function TestFunc1(funcRef) { funcRef(); } function TestFunc2(funcRef, obj) { funcRef.call(obj); } function TestFunc3(obj) { obj.alertValue(); } var testObj = new TestClass(11); testObj.test(); |
Functies zijn gewoon objecten in JS. Je kunt ze dus gewoon ook als parameter doorgeven. Je hebt echter ook de mogelijkheid om functies in de context van een bepaald object aan te roepen. Doorgaans doe je dat in de form van obj.func();, die mogelijkheid heb je echter alleen als func in de prototype van de constructor functie van obj voorkomt.
Stel dat obj een object van class ObjClass is. Dan zou dit precies gelijk zijn aan de bovenstaande aanroep: ObjClass.prototype.func.call(obj);. Op deze manier kun je functies ook aanroepen op objecten die deze functie helemaal niet in de prototype hebben staan. Het aanroepen van een bepaalde functie in de context van een object houdt in dat je binnen die functie met this kunt werken, waarbij this dan verwijst naar dat object. Als je een functie echter aanroept buiten de context van een object, dan verwijst this naar iets anders. (Ik weet niet zeker of het gedefineerd is, maar in Firefox verwijst hij dan naar het Window object.)
Dit is ook wat je in bovenstaande code terug ziet. Vooral TestClass.test is belangrijk. Ik roep de functie op 5 verschillende manieren aan. Daarvoor gebruik ik ook een paar hulp functies om aan te tonen hoe het werkt. In het eerste voorbeeld van ik de functie alertValue eerst op in een lokale variabel. Daarna roep ik hem aan, maar niet meer binnen de context van this. Wat er dus gebeurt is dat this binnen alertValue niet meer naar this in test verwijst. In het 2de geval gebeurt precies hetzelfde. Alleen wordt de functie dan als parameter meegegeven aan een andere functie die hem dan weer aanroept.
In voorbeeld 3 gebeurt wat anders. Daar vang ik this eerst op in de lokale variabel self, welke ik later nodig heb in de (anonieme) functie die ik doorgeef aan TestFunc1. TestFunc1 roept de gegeven functie aan die dan weer gebruik van self maakt. Dit is een belangrijk, maar (zeker in het begin) moeilijk concept om te snappen. Het heet closure, wat inhoudt dat een functie aangemaakt in een bepaalde scope zelf ook toegang heeft tot die scope, naast zijn eigen scope. Die omringende scope wordt er dus al het ware bij ingesloten. Hoewel self niet binnen de scope van de anonieme functie valt, heeft deze er wel toegang tot. Echter niet tot this, wat zeker belangrijk te onthouden is, omdat this altijd verwijst naar de context waarin een functie is aangeroepen (of geen).
In voorbeeld 4 roep ik TestFunc2 aan en geef 2 parameters. De eerste is de functie zelf en de 2de het object waarop ik de functie wil aanroepen. Dit zorgt dus dat this binnen alertValue nog steeds naar dezelfde this binnen test verwijst.
Het laatste voorbeeld is typische polymorphisme. TestFunc3 vraagt een object met een bepaalde interface (in dit geval moet functie alertValue geimplementeerd zijn) en roept daaruit een functie aan. Welk object of class het is, is niet belangrijk.
Mijn voorkeur voor jouw probleem gaat uit naar voorbeeld 3. Dit is de gemakkelijkste oplossing. Ik zou zeggen, ga nog eens wat opzoeken over closure en zorg dat je dit concept goed snapt. Het zal je zeker helpen bij het ontwikkelen van JS scripts.
heel erg bedankt!
ik denk dat ik het nu snap. wat ik dus (fout) deed was een functie object meegeven als parameter aan mijn andere object. in dat andere object werd die functie aangeroepen, maar gewoon als normale functie en dus buiten de object context. in deze normale functie heeft this geen betekenis (of refereert in ieder geval niet naar mijn object) en daarom werkte het niet. met jouw oplossingen (ik heb ook voor 3 gekozen) zorg je ervoor dat de functie wel in object context wordt aangeroepen, waardoor this weer beschikbaar wordt en alles dus werkt.
ik ga me zeker nog even verdiepen in die closure theorie, maar het principe is me in ieder geval duidelijk.
nogmaals bedankt
ik denk dat ik het nu snap. wat ik dus (fout) deed was een functie object meegeven als parameter aan mijn andere object. in dat andere object werd die functie aangeroepen, maar gewoon als normale functie en dus buiten de object context. in deze normale functie heeft this geen betekenis (of refereert in ieder geval niet naar mijn object) en daarom werkte het niet. met jouw oplossingen (ik heb ook voor 3 gekozen) zorg je ervoor dat de functie wel in object context wordt aangeroepen, waardoor this weer beschikbaar wordt en alles dus werkt.
ik ga me zeker nog even verdiepen in die closure theorie, maar het principe is me in ieder geval duidelijk.
nogmaals bedankt
Microsoft Windows: A thirty-two bit extension and graphical shell to a sixteen-bit patch to an eight-bit operating system originally coded for a four-bit microprocessor which was written by a two-bit company that can't stand one bit of competition