...

View Full Version : 2 noobie functions



morplug
09-08-2011, 12:10 AM
hey , i got 2 function , the one working and the other one is'nt

heres the functions :



var toDisplay = "f";
function human(){
var toAdd = toDisplay.substring(0,1);
setTimeout(human , 500);
document.getElementById('box').innerHTML += toAdd;
}
human(); // works (display "f" every half a sec)

function human2(toDisplay2){
var toAdd = toDisplay2.substring(0,1);
var t = setTimeout("human2(toDisplay2)" , 500);
document.getElementById('box').innerHTML += toAdd;
}
human2("dsd"); // not working (only display "d" and stop)


the first function works ( keep printing "f" every 0.5 sec )
the second function only work once and than stop ( print "d" and than stop )

what's the problem with the second function?

thanks , Mor.

Old Pedant
09-08-2011, 02:12 AM
That's because when the timeout fires, the code tries to execute *exactly* what you gave there, in the setTimeout:

human2(toDisplay2)

But by that time, the variable toDisplay2 no longer exists, so you get an error.

You have to code that this way:


function human2(toDisplay2){
var toAdd = toDisplay2.substring(0,1);
setTimeout("human2('" + toDisplay2 + "')" , 500);
document.getElementById('box').innerHTML += toAdd;
}
human2("dsd");

No point in assigning the setTimeout to the variable t because that variable, also, disappears as soon as the human2 function finishes.

p.s.: You can, of course, reverse the quotes and apostrophes. Makes no difference.


setTimeout('human2("' + toDisplay2 + '")' , 500);

DaveyErwin
09-08-2011, 02:44 AM
Here is another way ...


<body>
<div id="box"> </div>
</body>
<script>
function human2(toDisplay2){
(function inner(){
var toAdd = toDisplay2.substring(0,1);
setTimeout(inner , 500);
document.getElementById('box').innerHTML += toAdd;})()
}
human2("dsd");
</script>

this way toDisplay2 continues to exist.

DaveyErwin
09-08-2011, 03:08 AM
In case you get tired of seeing the d's go by ...


<body>
<div id="box"> </div>
<input type="button" value="stop!" onclick = "clearTimeout(t)">
</body>
<script>
function human2(toDisplay2){
(function inner(){
var toAdd = toDisplay2.substring(0,1);
t = setTimeout(inner , 500);
document.getElementById('box').innerHTML += toAdd;})()
}
human2("dsd");
</script>

Old Pedant
09-08-2011, 04:32 AM
And not to quibble--because Davey's code works--I would always add in var t = null; outside of any function both to ensure that the variable really *is* global and to give myself a convenient way to test to see if any timeout is active.


<body>
<div id="box"> </div>
<input type="button" value="stop!" onclick = "if ( t != null ) { clearTimeout(t); t = null; }">
</body>
<script>
var t = null;
function human2(toDisplay2){
(function inner(){
var toAdd = toDisplay2.substring(0,1);
t = setTimeout(inner , 500);
document.getElementById('box').innerHTML += toAdd;})()
}
human2("dsd");
</script>

My code there adds nothing at all to the functionality in this particular example. But that technique can be useful in other circumstances.

venegal
09-09-2011, 12:31 AM
I feel the need to clear things up a bit, since the replies are a bit beside the point.



You have to code that this way:


function human2(toDisplay2){
var toAdd = toDisplay2.substring(0,1);
setTimeout("human2('" + toDisplay2 + "')" , 500);
document.getElementById('box').innerHTML += toAdd;
}
human2("dsd");



The main problem with the original code is that it puts code into a string, instead of a function (which would create a closure, and all would be fine). While this approach here does work, it isn't really a solution; suppose the function human2 doesn't expect a string parameter but an array or an object now what are you going to do? Convert the parameter to a JSON string in order to be able to put it into the code string? That's just silly.

Generally speaking never put code into a string. If you do, you're entering a world of hurt (and undebuggability).



Here is another way ...


<body>
<div id="box"> </div>
</body>
<script>
function human2(toDisplay2){
(function inner(){
var toAdd = toDisplay2.substring(0,1);
setTimeout(inner , 500);
document.getElementById('box').innerHTML += toAdd;})()
}
human2("dsd");
</script>

this way toDisplay2 continues to exist.

That's the right idea, but it's a bit convoluted and makes the whole closure thing look more complicated than it really is.

Creating a closure in order to pass that local variable as a parameter is as easy as this:

function human2(toDisplay2) {
var toAdd = toDisplay2.substring(0,1);
document.getElementById('box').innerHTML += toAdd;
setTimeout(function () {human2(toDisplay2);} , 500);
}

There's no need for a named inner function.



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum