1

I am horrible at debugging and am totally confused as to why this won't work. Here is my situation:

I wrote a function to open several links into tabs and then perform a very simple operation on them. It wasn't working as I had anticipated so I rewrote it to just open one one link into one tab, which worked. This is what I have (simplified):

links=arrayFromGetElemenetsCall;
if(condition){
  theNewWindow=window.open(links[0]);
}
setTimeout("myFunction(theNewWindow)",5000);
}

function myFuntion(bob){
  bob.doStuff();
}

When I attempt to open more than one tab and save the window references into an array for future use I get an error. This is the simplified code for multiple windows:

var theArray=new Array();
links=arrayFromGetElemenetsCall;
for(conditions){
  if(condition){
    theArray[i]=window.open(links[i]);
  }
}
setTimeout("myFunction(theArray[0])",5000);}

function myFuntion(bob){
  bob.doStuff();
}

Which does not work. i get "Error: theArray is not defined" if and only if it is written into the setTimeout function. I have tried passing the entire array and then looping in myFunction as well as calling .doStuff() on bob[0].

What is it that i'm not seeing here?

Svante Svenson
  • 12,315
  • 4
  • 41
  • 45
Aaron Luman
  • 635
  • 1
  • 10
  • 29

3 Answers3

2

Yikes. First of all, get out of the habit of passing strings as the first argument to setTimeout and setInterval. setTimeout will implicitly use eval to execute that string, and eval is evil.

In this case, the secret eval is also the cause of your logical error. The snippet isn't enough to precisely diagnose your problem, but basically in the eval scope, theArray is not defined. A rewrite to use a closure is a possible approach:

setTimeout(function(obj){
    return function(){
        myFunction(obj);
    }
}(theArray[0]), 5000);
Community
  • 1
  • 1
Kenan Banks
  • 207,056
  • 34
  • 155
  • 173
2

(All decent browsers have popup blockers that will probably stop you from opening more than one new window.)

You'll want to change the following: setTimeout("myFunction(theArray[0])",5000);}

into:

setTimeout(function(){
  myFunction(theArray[0]);
}, 5000);

That way theArray will be in scope. Passing a string to setTimeout will probably run that code in the scope of window in the browser.

Svante Svenson
  • 12,315
  • 4
  • 41
  • 45
0

Is this what you're trying to do? I tried this on my firebug console and it printed out "I have 40" after two seconds.

var theArray = new Array();

for(var i = 0; i < 10; i++) {
   theArray[i] = i * 10;
}

setTimeout("func(theArray[4])", 2000);

function func(val) {
   console.log("I have " + val);
}
Vivin Paliath
  • 94,126
  • 40
  • 223
  • 295