的Javascript递归改进
问题描述:
有人在工作中开玩笑地发出了一封电子邮件,意在崩溃的浏览器,这是下面的Javascript递归改进
<html>
<script type="text/javascript">
function crash(){
for(i=0;i<5000000001;i++){
document.write(i);
}
}
</script>
<body onload="crash();">
</body>
</html>
一个HTML文件,反正它不会在Chrome和谈话做一个伟大的工作它引发了一场友好的竞赛,看看谁能够尽可能快地编写javascript来使页数达到50亿,而不会导致浏览器无响应或崩溃。
我想出了下面的一段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>
- 制造数和元素globabl
- 切换到文本而不是DIV输入
- 移动更新UI来设置回调
答
后
请勿使用.innerHTML = ...
显示号码。据this test,设置一个输入元件的value
属性是更有效的。
<input type="text" id="counter" value="0" />
如果不建立新的功能,我建议使用全局/局部变量,并通过一个函数引用作为参数传递给setTimeout
,或者在初始化使用setInterval
。
- 为
setTimeout(countToFiveBillion,0)
交换setTimeout("countToFiveBillion()",1)
。 说明:"countToFiveBillion()"
效率低下;首先,字符串被转换为一个函数并被调用,然后是另一个函数调用。建议的函数运行只需要调用一个函数,而不需要创建新函数。它也被称为更快的一秒。 - 提起极限(我是能够增加18701至20000)。解除限制后,我注意到
counter
值在每次超时之间更新。 - 固定在执行一些错误(在else区块取代
.innerHTML
与.value
)。
相关的代码:
<input type="text" id="counter" />
<script>
var counter, num = 0;
function countToFiveBillion(){
if(num < 5e9)
{
if(++num % 18701 == 0){
setTimeout(countToFiveBillion, 0);
counter.value = num;
} else {
countToFiveBillion();
}
} else {
counter.value = "number greater than 5 Billion";
}
}
function initiateCountDown(){
counter = document.getElementById('counter');
counter.value = num; //Init, show that the script is
countToFiveBillion();
}
window.onload = initiateCountDown;
</script>
答
Webworker例如,index.html的
<!DOCTYPE HTML>
<html>
<head>
<title>5 billion</title>
</head>
<body>
<input type="text" id="counter" value="0" />
<script type="text/javascript" charset="utf-8">
var
iCounter = document.getElementById('counter')
, counter = new Worker('worker.js');
iCounter.value = 0;
counter.addEventListener('message', function (e) {
iCounter.value = e.data;
}, false);
</script>
</body>
</html>
worker.js:
for (var i = 0; i < 5e9; i++) {
if (i % 18701 === 0) {
postMessage(i);
}
}
如果需要,计数可以分成多个工人。
我不完全知道如何传递一个函数在JS参考woudl我只是做的,而不是我目前做的方式this.countToFiveBillion? – msarchet
全局声明变量,然后更换'的setTimeout(..)''通过的setTimeout(countToFiveBillion,1)'。 –
是啊,有道理 – msarchet