简体   繁体   English

为什么使用JavaScript arguments.callee会导致RangeError

[英]Why does the use of JavaScript arguments.callee result in a RangeError

The code below throws an "Uncaught RangeError: Maximum call stack exceeded", and I'm not sure why. 下面的代码引发“未捕获的RangeError:超出最大调用堆栈”,但我不确定为什么。 I thought that this would be the series of events: 我认为这将是一系列事件:

the code runs on page load 代码在页面加载时运行

the timeout callback is set up 设置了超时回调

the call stack ends there 调用堆栈到此结束

after 5 seconds, the function is called 5秒钟后,该函数被调用

the timeout callback is set up again 再次设置超时回调

and the call stack ends 并且调用堆栈结束

etc. 等等

But the console output I get is: 但是我得到的控制台输出是:

xi=0
Uncaught RangeError: Maximum call stack size exceeded

the code: 编码:

<script>
    var xi = 0;
    (function(){
        window.console && console.log("xi=" +xi++);
        setTimeout(function(){
            arguments.callee();
        }, 5000);
    })();
</script>

Thank you for any help. 感谢您的任何帮助。

The innermost function (anonymous function) is calling itself. 最里面的函数(匿名函数)正在调用自身。 Your code is equivalent to 您的代码等同于

        setTimeout(function f(){
            f();
        }, 5000);

So this results in an endless recursion. 因此,这将导致无限递归。

What you want is: 您想要的是:

var xi = 0;
(function(){
    window.console && console.log("xi=" +xi++);
    var f = arguments.callee;
    setTimeout(function(){
        f();
    }, 5000);
})();

You're better off just using a named function. 您最好只使用命名函数。

var xi = 0;
(function namedFunction (){
    window.console && console.log("xi=" +xi++);
    setTimeout(function(){
      namedFunction();
    }, 5000);
})();

You could also create a helper function if you create intervals (that you want to run immediately) often. 如果您经常创建间隔(要立即运行),则也可以创建一个辅助函数。

var xi = 0;

function newInterval (duration, callback) {
    if (typeof callback !== 'function') return console.error('newInterval() requires a function');
    callback();
    return setInterval(callback, duration);
}

var intervalID = newInterval(5000, function () {
    console.log('xi=' + xi++);
});

Here's the jsfiddle to try it. 这是尝试的jsfiddle。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM