【问题标题】:simple javascript function definition problem简单的javascript函数定义问题
【发布时间】:2011-01-10 23:45:18
【问题描述】:
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() 没有定义的错误。怎么解决?

【问题讨论】:

  • 请发布您的实际代码。在大多数情况下不会发生这种情况。
  • 是的,它似乎工作正常:jsfiddle.net/ctrlfrk/Usvty(只要你有退出条件)

标签: javascript function mutual-recursion


【解决方案1】:

更新

您的更新代码与原始代码完全不同。问题似乎是您传递给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();
};

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

【讨论】:

  • @Devin:不用担心,很高兴有帮助。
  • 我不知道 OP 在哪里定义了 Second 和 First 函数,但如果他/她以与您相同的方式(在 onload 函数中),那么它很清楚为什么字符串 Second() 不起作用:setTimeout 在全局范围内评估字符串,但 Second 是 onload 回调的本地。它在全局范围内不可见。这可能是 OP 的问题。也只是想说点什么:D
  • @Felix:谢谢。我正在睡觉的路上,没有机会完成它......
【解决方案2】:

好的,我想我明白你的问题了。我打赌你的代码包含在一个函数中,对吧?那么就没有函数 Second 这样的东西了。

这不起作用:

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

但这会起作用:

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

【讨论】:

    【解决方案3】:

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

    在 Javascript 中,变量在函数调用时绑定得很晚。全局对象也只是另一个很晚才“绑定”的变量。一切都可以随时(异步)改变,这就是为什么一个函数不能要求另一个函数可用。 “缺失的”函数可能只是在调用函数之前由其他机制添加。只有在函数执行之前,JS-runtime 应该检查这个函数是否在作用域中可用。

    这就是它在 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 解释器检测为错误。

    我希望这会有所帮助, 尤文

    【讨论】:

    • 好的,我看到打字时问题发生了变化。我仍然希望我的评论有所帮助。
    猜你喜欢
    • 1970-01-01
    • 2015-04-07
    • 2011-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-07
    相关资源
    最近更新 更多