简单的javascript函数定义问题

时间:2011-01-10 23:45:19

标签: javascript function mutual-recursion

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 ();

问题是,当定义了First()时,我得到的错误是Second未定义。怎么解决这个问题?

3 个答案:

答案 0 :(得分:4)

<强>更新

您的更新代码与原始代码完全不同。问题似乎是你传递给setTimeout的字符串(这让我感到惊讶,但很容易被复制)。我会改变

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

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

...或者如果您需要将参数传递给Second

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

(请注意,函数声明结束时不需要;,但setTimeout之后不会发生错误[你实际上并不需要 它,在这种情况下,“分号插入”的恐怖将为你插入,但是......]。)

上面的第二个和第三个版本使用函数引用。你的原文使用了一个字符串,然后编译,这是不必要的,似乎是问题(如this example using the string fails,但是this one with the function reference works)。

原始答案

截至下面的答案,您问题中引用的代码是:

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

该代码可以正常工作。这是一个无限循环(好吧,不是无限,因为最终实现不会有更多的堆栈空间用于返回地址),但是直到它爆炸,因为它会工作正常。 Example

如果您的实际代码看起来更像这样,它将会失败:

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

...因为它非常不同,它使用函数表达式(它们作为逐步代码的一部分处理)而不是函数声明(其中在进入作用域之前,在任何分步代码之前进行处理,并且在定义First之前调用Second。有关函数表达式和函数声明之间区别的更多详细信息,请参阅this other answer here on StackOverflow

答案 1 :(得分:1)

好的,我想我看到了你的问题。我打赌你的代码包含在函数内部,对吧?那么就没有第二个功能。

这不起作用:

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

但这会奏效:

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

答案 2 :(得分:0)

我刚试过你的代码并调用了“Second();”第一。它在Chrome中运行良好。 它当然会永远循环。

在Javascript中,变量在调用函数时很晚才被绑定。全局对象也是另一个也很晚“绑定”的变量。一切都可以随时改变(异步),这就是为什么函数不能要求另一个函数可用的原因。 在调用函数之前,可能只是通过其他一些机制添加“missing”函数。只有在执行函数之前,JS运行时才应检查范围内是否有此函数。

这就是它在Chrome中运行的原因。在Javascript中你实际上是在做这样的事情:

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

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

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

调用GLOB["Second"]();就像Chrome中的一个魅力(当然还有循环)。也许你的浏览器/ JS-implementation / dev-tool对函数定义的限制更多,让你在定义之前不要使用函数。

然后您可以使用此obj["funcname"] = function() {}语法,该语法与function funcname(){}相同,但可能不会被“损坏的”JS解释器检测为错误。

我希望这有帮助, 尤文