Simple parameter passing within a setInternal() call?

T

Tuxedo

How can a simple string parameter be passed between two functions while
inside a setInterval call? For example:

function initialFunction(x){
alert(x);
setInterval('repeatingStuff(x)',5000);
}

function repeatingStuff(x){
alert(x);
}
....

<a href="..." onclick="initialFunction('param_x');">stuff</a>

But the error "x is not defined" results from ..Stuff(x) in
setInterval('repeatingStuff(x)',5000). How can the parameter between the
two functions be passed within the setInteval bit?

Many thanks,
Tuxedo
 
T

Tuxedo

Tuxedo wrote:

[...]
setInterval('repeatingStuff(x)',5000). How can the parameter between the

I thought I had tried this already but I must have simply got the quoting
wrong. Of course, this works:
setInterval('repeatingStuff("' + x + '")',5000);

Tuxedo
 
A

Andreas Bergmaier

Tuxedo said:
How can a simple string parameter be passed between two functions while
inside a setInterval call? For example:

function initialFunction(x){
alert(x);
setInterval('repeatingStuff(x)',5000);
}

function repeatingStuff(x){
alert(x);
}
...

<a href="..." onclick="initialFunction('param_x');">stuff</a>

But the error "x is not defined" results from ..Stuff(x) in
setInterval('repeatingStuff(x)',5000). How can the parameter between the
two functions be passed within the setInteval bit?

x must be in the scope of the second function. Therefore, you should
define repeatingStuff inside the initialFunction:

function initialFunction(x){
alert(x);
function repeatingStuff(x){
alert(x);
}
setInterval(repeatingStuff,5000);
}

or shorter:

function initialFunction(x){
alert(x);
setInterval( function(x){
alert(x);
}, 5000);
}

You should pass a function to setIntervall/Timeout, instead of a code to
be evaluated each time (slow & buggy).

Another alternative is to use bind() or other functions, to return a
function which calls repeatingStuff with the needed parameters:

function repeatingStuff(){...}
function initialFunction(x){
alert(x);
setInterval( repeatingStuff.bind(this, x), 5000);
}

Greetings,
Bergi
 
T

Thomas 'PointedEars' Lahn

Andreas said:
x must be in the scope of the second function.

In the scope _chain_.
Therefore, you should define repeatingStuff inside the initialFunction:

function initialFunction(x){
alert(x); ^ ^--------------'
function repeatingStuff(x){ ^
alert(x); | ^--------------'
}
setInterval(repeatingStuff,5000);
}

or shorter:

function initialFunction(x){
alert(x); ^ ^--------------'
setInterval( function(x){
alert(x); ^ ^------------'
}, 5000);
}

This does not work, because in the context of the function (referred by
`repeatingStuff'), `x' is bound to the inner function's argument `x' (which
is not passed a useful value from the DOM implementation anyway) and not to
that of the inner function's definition context. Please test before you
post, or clearly mark code as untested.
You should pass a function to setIntervall/Timeout, instead of a code to
be evaluated each time (slow & buggy).

The function code also will have to be evaluated each time. But it is true
that evaluating the string value as a Program is less efficient and more
error-prone than that.
Another alternative is to use bind() or other functions, to return a
function which calls repeatingStuff with the needed parameters:

function repeatingStuff(){...}
function initialFunction(x){
alert(x);
setInterval( repeatingStuff.bind(this, x), 5000);
}

This works in implementations of ECMAScript 5.x or where you have a suitable
scripting framework that emulates Function.prototype.bind(), but it is
unnecessarily inefficient by comparison.


PointedEars
--
If you get a bunch of authors […] that state the same "best practices"
in any programming language, then you can bet who is wrong or right...
Not with javascript. Nonsense propagates like wildfire in this field.
-- Richard Cornford, comp.lang.javascript, 2011-11-14
 
A

Andreas Bergmaier

Thomas said:
This does not work, because in the context of the function (referred by
`repeatingStuff'), `x' is bound to the inner function's argument `x' (which
is not passed a useful value from the DOM implementation anyway) and not to
that of the inner function's definition context.

I'm sorry, I forgot the essential thing when copying the example code :-(
@Tuxedo: The thing is to have only one variable "x". The code should be

function initialFunction(x){
alert(x);
setInterval( function(){
alert(x);
}, 5000);
}
This works in implementations of ECMAScript 5.x or where you have a suitable
scripting framework that emulates Function.prototype.bind(), but it is
unnecessarily inefficient by comparison.

Is it? Unnecessarily in this case, yes, but if you have defined
"repeatingStuff" elsewhere it is imho much more elegant than coding

var x;
setInterval( function(){
doRepeatingStuffWith(x);
}, 5000);

Bergi
 
T

Thomas 'PointedEars' Lahn

Andreas said:
Is it? Unnecessarily in this case, yes, but if you have defined
"repeatingStuff" elsewhere it is imho much more elegant than coding

var x;
setInterval( function(){
doRepeatingStuffWith(x);
}, 5000);

That is not even equivalent in the first place. Clearly you do not
understand bind(). Please refrain from recommending it until you do.


PointedEars
 
A

Andreas Bergmaier

Thomas said:
That is not even equivalent in the first place. Clearly you do not
understand bind(). Please refrain from recommending it until you do.

I do, and I never said it was to be equivalent. Of course bind() needs a
context to set, dereferences x, and builds a new function. That even
could be useful (I'm not sure what the OP needs), so why shouldn't I
mention it as an alternative?

Bergi
 
T

Tuxedo

Andreas Bergmaier wrote:

[...]
@Tuxedo: The thing is to have only one variable "x". The code should be

function initialFunction(x){
alert(x);
setInterval( function(){
alert(x);
}, 5000);
}

Thanks - works great! Much better than my quoted parameters as in
Stuff("' + x + '")',5000 etc.

Tuxedo

[..]
 
D

Dr J R Stockton

Sat said:
Tuxedo wrote:

[...]
setInterval('repeatingStuff(x)',5000). How can the parameter between the

I thought I had tried this already but I must have simply got the quoting
wrong. Of course, this works:
setInterval('repeatingStuff("' + x + '")',5000);

That will use the value of x at call time, if x is simple or an
expression.

Another way is to pass x as a global variable; or, perhaps more clearly,
as a property of a global Object reserved and named, or otherwise
suitable, for the purpose. Actually, repeatingStuff is such an Object.

That eliminates conversions to/from String, which may be inexact.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top