[Javascript] Meegeven parameter aan gequoteerde functie

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • Devilly
  • Registratie: Januari 2009
  • Niet online
Ik ben wat aan het spelen met Javascript, maar loop nu tegen een probleem aan. Bij het aanroepen van functies moeten deze functies gequoteerd worden. Hieronder staat een voorbeeld met een setInterval():

JavaScript:
1
window.setInterval("ik.changeWidth()", 100);


Nu is het op deze manier echter onmogelijk om parameters aan de functie mee te geven. Nu heb ik lopen Googlen en kwam ik rare constructies tegen waarbij je door met de quotes te spelen het wel werkend zou moeten kunnen krijgen, maar dat bleek toch niet te werken. Daarna kwam ik een voorbeeld tegen, waarbij de functie op de volgende manier in het bovenstaande voorbeeld zou worden verwerkt:

JavaScript:
1
window.setInterval(function(){ik.changeWidth()}, 100);


Vol blijdschap kon ik zien dat de bovenstaande aanroep werkt (ook als ik er parameters bij invoer). Dit werkt echter niet als ik het bij een onclick op de volgende manier implementeer (de gelijkwaardige aanroep m.b.v. de quotes werkt echter wel):

JavaScript:
1
<input type = "button" id = "input" value = "Druk hier!" onclick = function(){ik.changeWidth()};>


Kan iemand mij vertellen wat hier niet aan klopt? Ik vermoed dat het komt doordat ik Javascript buiten de script-tags gebruik, maar ik zou niet weten hoe ik het anders kan oplossen. Een alternatief zou ik dus ook erg waarderen. Hierbij snap ik eigenlijk niet hoe de code 'function(){*naam van de functie*}' werkt en zou ik het dus ook erg op prijs stellen als iemand mij dit zou kunnen toelichten. Natuurlijk heb ik hier zelf ook al over nagedacht. Het meest logische lijkt mij dat er een naamloze functie wordt aangeroepen die dan weer de eigenlijk bedoelde functie aanroept. Als dit het geval is, lijkt het mij stug dat dit de beste/mooiste oplossing is. Het klinkt namelijk als een goedkope work-around.


Devilly

Acties:
  • 0 Henk 'm!

  • MachoM
  • Registratie: April 2003
  • Laatst online: 09:53
Het probleem is dat het onderste voorbeeld gaan javascript is, maar (X)HTML. Een html property moet altijd netjes qoutjes om zich heen hebben. Dit heeft dus eigenlijk niets met javascript zelf te maken.

Acties:
  • 0 Henk 'm!

  • Snake
  • Registratie: Juli 2005
  • Laatst online: 07-03-2024

Snake

Los Angeles, CA, USA

HTML:
1
<input ... onclick="obj.functie(this.value);" />


Wat werkt hier niet aan ? :)

[ Voor 15% gewijzigd door Snake op 17-04-2009 20:15 ]

Going for adventure, lots of sun and a convertible! | GMT-8


Acties:
  • 0 Henk 'm!

  • Devilly
  • Registratie: Januari 2009
  • Niet online
@ MachoM: heb je misschien ook een oplossing voor het probleem, ondanks het feit dat het misschien niet in het goede subforum is gepost?

@ Snake: ik zou niet weten wat er niet werkt, maar het feit dát het niet werkt, heb ik hier wel ondervonden. Ik zou zelf gokken dat de gequoteerde inhoud pas later wordt geëvalueerd en de parameters dan niet meer meegegeven kunnen worden (met welke reden dan ook), maar aangezien ik nog maar net begin, kan ik hier eigenlijk geen echt statement over maken.

*** Edit ***

Op de een of andere manier lukt het nu wel. Natuurlijk ga ik even onderzoeken wat de fout was en laat ik dat ook nog even weten. :)

*** Edit ***

Het blijkt dus zo te zijn dat gequoteerde inhoud welke niet uit variabelen bestaat goed wordt verwerkt. In het eerste voorbeeld zou ik dus tussen de haakjes het getal 1000 kunnen zetten en dan werkt het, maar als ik een variable width aanmaak welke het getal 1000 bevat en deze tussen de haakjes zet, werkt het niet.

[ Voor 66% gewijzigd door Devilly op 17-04-2009 20:29 ]


Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Baisc escaping hoor. Je (X)HTML attributen horen tussen quotes. Als je quotes binnen quotes wil gebruiken moet je gewoon escapen. Ik zie het hele probleem dan ook niet.

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

  • Devilly
  • Registratie: Januari 2009
  • Niet online
Het HTML deel werkt nu, maar hier kom ik echter echt niet uit (ik zal wel iets over het hoofd zien):

JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
    function changeWidth(wijdte)
    {
        if(parseInt(document.getElementById(this.id).style.width.slice(0,-2)) < wijdte)
        {
            document.getElementById(this.id).style.width = parseInt(document.getElementById(this.id).style.width.slice(0,-2)) + 1;
            window.setInterval("ik.changeWidth(wijdte)", 100);
        }
        else
        {
            ik.changeHeight();
        }
    }


Waarom pakt hij de variabele wijdte in de window.setInterval() niet?

Acties:
  • 0 Henk 'm!

  • SKiLLa
  • Registratie: Februari 2002
  • Niet online

SKiLLa

Byte or nibble a bit ?

Moet dat niet simpelweg:

JavaScript:
1
window.setInterval("ik.changeWidth(" + wijdte + ")", 100);


zijn ?

'Political Correctness is fascism pretending to be good manners.' - George Carlin


Acties:
  • 0 Henk 'm!

  • _Thanatos_
  • Registratie: Januari 2001
  • Laatst online: 05-09 14:39

_Thanatos_

Ja, en kaal

Nee dat moet dan zijn:
JavaScript:
1
window.setInterval(function() { ik.changeWidth(wijdte) }, 100);

Of als je IE6 mag negeren:
JavaScript:
1
window.setInterval(ik.changeWidth, 100, wijdte);

Want setInterval en setTimeout met string-parameter zijn impliciet eval(), en dat is evil ;)

[ Voor 17% gewijzigd door _Thanatos_ op 18-04-2009 02:35 ]

日本!🎌


Acties:
  • 0 Henk 'm!

  • Devilly
  • Registratie: Januari 2009
  • Niet online
Man, ik ben echt niet helemaal wakker *kijkt naar zijn eigen openingspost*. Is er ergens een goede uitleg te vinden over die function-declaratie? Als ik google, krijg ik voornamelijk algemene informatie en uitleg over algemene functies, maar dat is dus niet wat ik wil. Graag zou ik willen weten hoe de function-declaratie binnen de setInterval() werkt. Ik zou echter niet weten hoe ik mijn zoekresultaten moet specificeren op het bovenstaande function voorbeeld.

[ Voor 11% gewijzigd door Devilly op 18-04-2009 08:23 ]


Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 23:09

crisp

Devver

Pixelated

Ben ik nu de enige die zich afvraagt wat 'ik' in deze context is?

Wat leuke voorbeeldjes:
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
function myClass()
{
    this.width = 100;
}
myClass.prototype.alertWidth = function()
{
    alert(this.width);
}

// global
var ik = new myClass;

ik.alertWidth(); // 100
window.setTimeout("ik.alertWidth()", 100); // 100
window.setTimeout(function() { ik.alertWidth(); }, 100); // 100
window.setTimeout(ik.alertWidth, 100); // undefined

function foo()
{
    // local to function
    var jij = new myClass;

    jij.alertWidth(); // 100
    window.setTimeout("jij.alertWidth()", 100); // error: 'jij' is undefined
    window.setTimeout(function() { jij.alertWidth(); }, 100); // 100
    window.setTimeout(jij.alertWidth, 100); // undefined
}

foo();

Intentionally left blank


Acties:
  • 0 Henk 'm!

  • Devilly
  • Registratie: Januari 2009
  • Niet online
@ crisp: 'ik' is een variabele die een object bevat van de functie/klasse 'divSlide'. 'changeWidth' is dan ook weer een methode die bij die klasse hoort.

-----

Het werkt nu allemaal en wat het nog vele malen mooier maakt, is dat ik het snap! Bedankt voor de uitleg en hulp. :) In het vervolg zal ik ook proberen mijn probleemstelling wat beter te omschrijven, want die is niet altijd helemaal goed aangekomen, heb ik zo het gevoel.

Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 23:09

crisp

Devver

Pixelated

Devilly schreef op zaterdag 18 april 2009 @ 20:36:
@ crisp: 'ik' is een variabele die een object bevat van de functie/klasse 'divSlide'. 'changeWidth' is dan ook weer een methode die bij die klasse hoort.
Je 'ik' is dus daadwerkelijk een instance van die class en globaal gedefinieerd begrijp ik.
Het werkt nu allemaal en wat het nog vele malen mooier maakt, is dat ik het snap!
Da's mooi. Waar het mij vooral om ging is te laten zien dat de verschillende manieren van het aanroepen van je method niet equivalent zijn, en dat heeft alles te maken met de scope waar je 'ik' variabele beschikbaar is en de scope waarin je method wordt uitgevoerd. De twee voorbeelden van _Thanatos_ waren bijvoorbeeld al niet equivalent ;)

Intentionally left blank


Acties:
  • 0 Henk 'm!

  • Snake
  • Registratie: Juli 2005
  • Laatst online: 07-03-2024

Snake

Los Angeles, CA, USA

crisp schreef op zaterdag 18 april 2009 @ 12:09:
Ben ik nu de enige die zich afvraagt wat 'ik' in deze context is?

Wat leuke voorbeeldjes:
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
function myClass()
{
    this.width = 100;
}
myClass.prototype.alertWidth = function()
{
    alert(this.width);
}

// global
var ik = new myClass;

ik.alertWidth(); // 100
window.setTimeout("ik.alertWidth()", 100); // 100
window.setTimeout(function() { ik.alertWidth(); }, 100); // 100
window.setTimeout(ik.alertWidth, 100); // undefined

function foo()
{
    // local to function
    var jij = new myClass;

    jij.alertWidth(); // 100
    window.setTimeout("jij.alertWidth()", 100); // error: 'jij' is undefined
    window.setTimeout(function() { jij.alertWidth(); }, 100); // 100
    window.setTimeout(jij.alertWidth, 100); // undefined
}

foo();
Waarom is bij het 2de voorbeeld de gequote functie een probleem en de anonymous niet?

Going for adventure, lots of sun and a convertible! | GMT-8


Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 23:09

crisp

Devver

Pixelated

Snake schreef op zaterdag 18 april 2009 @ 21:21:
[...]

Waarom is bij het 2de voorbeeld de gequote functie een probleem en de anonymous niet?
timeouts en intervals worden in de globale scope uitgevoerd. De gequote functie is basically gewoon een string die geëvalueerd wordt. In de globale scope is de variabele 'jij' niet bekend, hence de error.
De anonymous functie wordt gedefinieerd binnen de scope van de functie 'foo' en heeft daarmee wel toegang tot de variabelen binnen die scope; je creëert een zogenaamde 'closure' :)

Intentionally left blank


Acties:
  • 0 Henk 'm!

  • Devilly
  • Registratie: Januari 2009
  • Niet online
Die 'ik.alertWidth' en 'jij.alertWidth' zouden variabelen (attributen, velden) van de klasse/het object zijn, als ze zouden bestaan, toch?

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 16:37

.oisyn

Moderator Devschuur®

Demotivational Speaker

Het hele punt is dat de string die je meegeeft niet wordt geëvalueerd in de context van de functie waarin je die aanroep doet. Een voorbeeld:
JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
function myeval(str)
{
    eval(str);
}

function foo()
{
    var i = 3;
    eval("alert(i);");   // 3
    myeval("alert(i);"); // undefined
}

foo();

De eerste keer wordt direct eval aangeroepen, op dat punt, dus in foo(), is de variabele genaamd 'i' bekend. De tweede keer wordt de string meegegeven aan een andere functie die vervolgens de eval() doet. Die andere functie kent geen variabele genaamd 'i'.

De setTimeout() functie werkt in principe precies zoals die myeval(). De string die je meegeeft wordt niet geëvalueerd in je changeWidth() functie maar op een later punt, en dus is 'ik' onbekend.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Devilly
  • Registratie: Januari 2009
  • Niet online
Dat verschil snap ik nu. Het enige wat ik nu nog niet helemaal snap, is wat het verschil is tussen


JavaScript:
1
window.setTimeout("jij.alertWidth()", 100);


en

JavaScript:
1
window.setTimeout(jij.alertWidth, 100);


Ik snap het verschil tussen een aanroep met aanhalingstekens en haakjes en een aanroep zonder beide niet.

Acties:
  • 0 Henk 'm!

  • HuHu
  • Registratie: Maart 2005
  • Niet online
Het eerste geval (met quotes) is de myeval van hierboven. Oftewel: het omzetten van de gequote string naar code wordt ergens anders gedaan dan op de plaats waar je die string plaatst.

Het tweede geval (zonder quotes) is de eval van hierboven. De code wordt direct op die plaats uitgevoerd.

Acties:
  • 0 Henk 'm!

  • Bosmonster
  • Registratie: Juni 2001
  • Laatst online: 16:31

Bosmonster

*zucht*

HuHu schreef op maandag 20 april 2009 @ 09:41:

Het tweede geval (zonder quotes) is de eval van hierboven. De code wordt direct op die plaats uitgevoerd.
Die tweede werkt ook niet zoals je in de voorbeelden kunt zien. De functiereference wordt meegegeven, maar is bij het uitvoeren de relatie met z'n instance (jij) kwijt.

Lang leve anonymous functions en closures :)

Acties:
  • 0 Henk 'm!

  • Guillome
  • Registratie: Januari 2001
  • Niet online

Guillome

test

De 2e een eval? De 2e is geen eval. Maar je stuurt de functie als object mee naar de timeout.

JavaScript:
1
2
3
4
5
6
7
8
9
function test(f)
{
  if (f) f();
}
function test2()
{
  alert(1);
}
test(test2);

If then else matters! - I5 12600KF, Asus Tuf GT501, Asus Tuf OC 3080, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 16:37

.oisyn

Moderator Devschuur®

Demotivational Speaker

Devilly schreef op maandag 20 april 2009 @ 09:24:
Dat verschil snap ik nu. Het enige wat ik nu nog niet helemaal snap, is wat het verschil is tussen


JavaScript:
1
window.setTimeout("jij.alertWidth()", 100);


en

JavaScript:
1
window.setTimeout(jij.alertWidth, 100);


Ik snap het verschil tussen een aanroep met aanhalingstekens en haakjes en een aanroep zonder beide niet.
alertWidth is een property van 'jij', wat toevallig een functie is. Als je jij.alertWidth() doet (dus de aanroep van die functie), dan wordt de 'this' in alertWidth() gelijk aan 'jij'. Echter, als je dit doet:
JavaScript:
1
2
var f = jij.alertWidth;
f();

Dan wordt alertWidth() wel aangeroepen, maar er is geen 'this'. Je roept immers gewoon f() aan, en niet jij.f() (wat niet werkt aangezien 'f' gewoon een variabele is en geen property van 'jij'). Vandaar dat je een functie moet maken die weet waar 'jij' naartoe wijst zodat hij de juiste call kan doen. Oftewel:
JavaScript:
1
2
var f = function() { jij.alertWidth(); }
f(); // nu is ie wel goed

[ Voor 3% gewijzigd door .oisyn op 20-04-2009 12:28 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Guillome
  • Registratie: Januari 2001
  • Niet online

Guillome

test

.oisyn schreef op maandag 20 april 2009 @ 11:24:
[...]
Echter, als je dit doet:
JavaScript:
1
2
var f = jij.alertWidth();
f();
Moet dat niet zijn
JavaScript:
1
2
var f = jij.alertWidth;
f();

If then else matters! - I5 12600KF, Asus Tuf GT501, Asus Tuf OC 3080, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router


Acties:
  • 0 Henk 'm!

  • Bosmonster
  • Registratie: Juni 2001
  • Laatst online: 16:31

Bosmonster

*zucht*

Guillome schreef op maandag 20 april 2009 @ 12:10:
[...]

Moet dat niet zijn
JavaScript:
1
2
var f = jij.alertWidth;
f();
Ja, zelfs de grote .oisyn maakt wel eens een typfoutje :)

Overigens kun je de relatie herstellen middels de call() en apply() methods.

[ Voor 13% gewijzigd door Bosmonster op 20-04-2009 12:13 ]


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 16:37

.oisyn

Moderator Devschuur®

Demotivational Speaker

Guillome schreef op maandag 20 april 2009 @ 12:10:
[...]

Moet dat niet zijn
JavaScript:
1
2
var f = jij.alertWidth;
f();
Dat staat er toch? O-)

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.

Pagina: 1