Eval() Alternative?

M

McKirahan

I said I wouldn't use "eval()" anymore but I need help to do it.

Below is some stripped-down code (4 lines; watch for word-wrap) extracted
from USGA.COM that preloads images:

main_nav_home_F1 = new Image(153,21); main_nav_home_F1.src =
"images/main_nav_home.gif";
main_nav_home_F2 = new Image(153,21); main_nav_home_F2.src =
"images/main_nav_home_F2.gif";
main_nav_about_F1 = new Image(153,21); main_nav_about_F1.src =
"images/main_nav_about.gif";
main_nav_about_F2 = new Image(153,21); main_nav_about_F2.src =
"images/main_nav_about_F2.gif";

Since there are two variations of 20 images, I thought a loop would be more
efficient.

The following works (I think) but it uses "eval()".

<script type="text/javascript">
if (document.images) {
var imgs = new Array();
imgs[0] = "home";
imgs[1] = "about";
// imgs[#] = etc.
var what = "";
for (var i=0; i<imgs.length; i++) {
what = "main_nav_" + imgs;
eval(what + "_F1 = new Image(153,21); " + what + "_F1.src =
\"images/" + what + ".gif\"");
eval(what + "_F2 = new Image(153,21); " + what + "_F2.src =
\"images/" + what + "_F2.gif\"");
}
}
</script>

I have 2 questions:

1) How would I eliminate the use of "eval()"?

2) Is there a better way to do this?

Thanks in advance.

P.S. I'm not with the USGA; I'm just considering the technique they used.
 
R

Richard Cornford

McKirahan wrote:
<script type="text/javascript">
if (document.images) {

Why this test? Your function does not use the document.images
collection. The environment feature that it does use is the global -
Image - constructor so test to verify that function/object exists would
make more sense. Using - typeof - :-

if(typeof Image != 'undefined'){
...
}

- or a type-converting test:-

if(this.Image){ // the - this - keyword is a reference
// to the global object in code executing
// in the global context.
...
}

- or:-

if(window.Image){
...
}

(or via whatever other reference to the global object you have created
or is available)

Testing one object and then using another is "object inference" and is
not appropriate for Internet browser scripting (because the inferences
are not guaranteed to be valid).
var imgs = new Array();
imgs[0] = "home";
imgs[1] = "about";
// imgs[#] = etc.

var imgs = [ // Use an Array literal to pre-populate
// a created Array in one statement.
"home",
"about"
// etc. (paying attention to the commas
// in Array literals.)
];
var what = "";
for (var i=0; i<imgs.length; i++) {
what = "main_nav_" + imgs;
eval(what + "_F1 = new Image(153,21); " + what +
"_F1.src = \"images/" + what + ".gif\"");

1) How would I eliminate the use of "eval()"?

this[what+"_F1"] = new Image(153,21);
this[what+"_F1"].src = "images/"+ what+".gif";

- or:-

window[what+"_F1"] = new Image(153,21);
window[what+"_F1"].src = "images/"+ what+".gif";

- Or Creating a single global object:-

var exampleGlobalObject = {};

- and then assign the stored Image objects as named properties of that
object (reduces pollution of the global namespace):-

exampleGlobalObject[what+"_F1"] = new Image(153,21);
exampleGlobalObject[what+"_F1"].src = "images/"+ what+".gif";

And if you had read the resource linked to from quick answer 39 in the
FAQ you would not have had to ask this question.
2) Is there a better way to do this?

The posted code does not define the problem that it is intended to
solve, so there is no way of judging what would qualify as better.

Richard.
 
P

peter seliger

hi McKirahan,


just answering your fist question:


in javascript the dot operator "." is not the
one and only way of how object properties can
be addressed - there is always the alternative
with using the "square bracket syntax";

if there was an property prop01 belonging to
an object obj01 one could address it not only
like this obj01.prop01 but also
like that obj01["prop01"] with the second way
offering the chance for addressing objects and
object properties in case object names or property
names are available as string values only;

the given example is supposed to create gloabal
variables only by some known keywords and a known
naming schema;

for global variables the square bracket notation
can be used too, since those variables are nothing
else than properties of the scripting host - in web
browsers the host is represented by the window object;
(it should be familar to you cause it is used for
-just mentioning one example- addressing frames:
window.frames)

in order to create or to access a global variable
named "main_nav_home_F1" simply write:


window["main_nav_home_F1"]


using this for your example:

window["main_nav_home_F1"] = new Image();
window["main_nav_home_F1"].src = "whatEver.mime";



so long - peterS. - (e-mail address removed)
 
M

McKirahan

peter seliger said:
"McKirahan" <[email protected]> wrote in message
hi McKirahan,


just answering your fist question:



in javascript the dot operator "." is not the
one and only way of how object properties can
be addressed - there is always the alternative
with using the "square bracket syntax";

[snip]

Excellent clarification; thank you.
 

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,779
Messages
2,569,606
Members
45,239
Latest member
Alex Young

Latest Threads

Top