有个同事开玩笑地发送了一封包含以下内容的 html 文件,旨在让你的浏览器崩溃
<html>
<script type="text/javascript">
function crash(){
for(i=0;i<5000000001;i++){
document.write(i);
}
}
</script>
<body onload="crash();">
</body>
</html>
无论如何,在Chrome中它的效果并不好,因此有人提出了一个友好的竞赛,看谁能够尽快编写Javascript代码,使页面在不导致浏览器无响应或崩溃的情况下计数到5,000,000,000。我想出了以下一段Javascript代码,旨在在Chrome中使用。<html>
<script type="text/javascript">
function countToFiveBillion(counter, num){
if(num < 5000000000)
{
num++;
if(num % 18700 == 0){
counter.innerHTML = num;
setTimeout(function() {countToFiveBillion(counter, num)}, 1);
} else {
countToFiveBillion(counter, num);
}
}
}
function initiateCountDown()
{
var counter = document.getElementById("counter");
var num = +counter.innerHTML;
countToFiveBillion(counter, num);
}
</script>
<body onload="initiateCountDown();">
<div id="counter">0</div>
</body>
</html>
这段代码只能在Chrome浏览器中运行的原因是我使用了setTimeout
调用来避免在Chrome中创建一个栈溢出。(Chrome允许递归调用的最大堆栈大小超过其他所有浏览器)。
有没有办法让计数更快?我认为我可以在它引起溢出之前稍微增加计数的数量(不到100)。唯一的限制是必须在计数时显示尽可能多的数字。
改进后的代码:
<html>
<script type="text/javascript">
var counter;
var num = 0;
function countToFiveBillion(){
if(num < 5000000000)
{
num++;
if(num % 18701 == 0){
setTimeout("countToFiveBillion()", 1);
counter.value = num;
} else {
countToFiveBillion();
}
} else {
counter.value = "number greater than 5 Billion";
}
}
function initiateCountDown()
{
counter = document.getElementById('counter');
countToFiveBillion();
}
</script>
<body onload="initiateCountDown();">
<input type="text" id="counter" value="0" />
</body>
</html>
- 将计数器和元素设为全局变量
- 使用文本输入代替 div 元素
- 将更新 UI 放在设置回调之后
setTimeout(..)
替换为setTimeout(countToFiveBillion, 1)
。 - Rob W