0
function First () {
setTimeout("Second()", 50)
};

function Second () {  //I'm very confident this conditional works fine
 if  (document.getElementsByClassName("l")[0].href ==
      document.getElementById("myFrame").getAttribute("src"))  
   {  
   First();                                       
   }
 else
   {
   var newLink = document.getElementsByClassName("l")[0].href;        //
   document.getElementById("myFrame").setAttribute("src", newLink);
   }};

First ();

The problem is that when First() is defined, I get the error that Second isn't defined. How can this be solved?

2
  • 2
    Please post your actual code. That will not happen in most circumstances. Commented Jan 10, 2011 at 23:47
  • Yeah it seems to work fine: jsfiddle.net/ctrlfrk/Usvty (as long as you have an exit condition) Commented Jan 11, 2011 at 0:00

3 Answers 3

4

Update

Your updated code is quite different from your original code. The problem appears to be the string you're passing to setTimeout (which surprised me, but was easily replicated). I would change

function First () {
    setTimeout("Second()", 50)
};

to

function First () {
    setTimeout(Second, 50);
}

...or if you need to pass parameters to Second:

function First() {
    setTimeout(function() {
        Second(param0, param1);
    }, 50);
}

(Note that there's no need for a ; at the end of a function declaration, but one after the setTimeout wouldn't go amiss [you don't actually need it, the horror that is "semicolon insertion" will insert it for you in this case, but...].)

The second and third versions above use a function reference. Your original uses a string which is then compiled, which is unnecessary and appears to be the problem (as this example using the string fails, but this one with the function reference works).

Original Answer

As of the answer below, the code quoted in your question was:

function First() {Second();};
function Second() {First();};

That code will work just fine. It's an infinite loop (well, not infinite, because eventually the implementation won't have any more stack space for return addresses), but until it blows up because of that it'll work fine. Example

It will fail if your actual code looks more like this:

var First = function() {
    Second();
};
First();
var Second = function() {
    First();
};

...because that's very different, it uses function expressions (which are processed as part of the step-by-step code) rather than function declarations (which are processed upon entry to the scope, before any step-by-step code) and it has a call to First before Second is defined. See this other answer here on StackOverflow for more detail on the distinction between a function expression and a function declaration.

Sign up to request clarification or add additional context in comments.

2 Comments

I don't know where the OP defines the Second and First functions but if he/she is doing it the same way you do (in the onload function), then it is clear why the string Second() does not work: setTimeout evaluates the string in global scope, but Second is local to the onload callback. It is not visible in global scope. This might be the OPs problem. Just wanted to say something too :D
@Felix: Thank you. I was en route to bed and hadn't had a chance to work it through...
1

Ok, I think I see your problem. I bet your code wrapped inside of a function, right? Then there would be no such thing as function Second.

This will not work:

(function() {
    function First () {
        setTimeout("Second()", 50)
    }
    function Second () {
        alert('hi!');
    }
    First();
})();

But this will work:

(function() {
    function First () {
        setTimeout(Second, 50)
    }
    function Second () {
        alert('hi!');
    }
    First();
})();

Comments

0

I just tried your code and called "Second();" first. It worked fine in Chrome. It will loop forever of course.

In Javascript variables are bound very late at invocation of a function. The global object is also just another variable that is also "bound" very late. Everything can change at any time (asynchronously) that's why a function must not require that another function is available. The "missing" function might just be added by some other mechanism just before the function is invoked. Only just before a function is executed, the JS-runtime should check if this functions is available in the scope.

That's why it works in Chrome. In Javascript you are actually doing something like this:

var GLOB = this; // bind global obj to variable

GLOB["First"] = function() {
   GLOB["Second"]();
};

GLOB["Second"] = function() {
   GLOB["First"]();
};

Invoking GLOB["Second"](); works like a charm in Chrome (and it loops of course). maybe your browser/JS-implementation/dev-tool is more restrictive regarding function definitions, and let's you not use functions before they are defined.

Then you might use this obj["funcname"] = function() {} syntax, which does the same as function funcname(){}, but might not be detected as error by your "broken" JS-interpreter.

I hope this helps, Juve

1 Comment

OK, I see the problem changed while typing. I still hope my comment helps.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.