JavaScriptの再帰処理の限界
JavaScriptの再帰処理をarguments.calleeを使って書くか、関数リテラル名指定で自分を呼び出すかでエラーになった時の挙動が違ったのでメモ。
arguments.calleeの場合
ブラウザ | エラーになる回数 | エラーメッセージ | メモ |
---|---|---|---|
IE6 | 438 | スタック領域が不足しています | catchできない |
IE7 | 1747 | stack over flow at line XX. | catchできない window.onerrorでハンドルしようとするとIEがクラッシュ |
Firefox 3.0 | 2999 | too much recursion | catchできない |
Safari 4 Beta | 40326 | Maximum call stack size exceeded. | catchできない |
関数リテラル名指定の場合
ブラウザ | エラーになる回数 | エラーメッセージ | メモ |
---|---|---|---|
IE6 | 462 | スタック領域が不足しています | catchできる |
IE7 | 2495 | スタック領域が不足しています | catchできる |
Firefox 3.0 | 2999 | too much recursion | catchできる |
Safari 4 Beta | 43686 | Maximum call stack size exceeded. | catchできる |
検証コード
<html> <head> <title>Limit of Recursion</title> <script> var setup = function(){ window.onerror = function(e, fileName, row){ alert("catch失敗\nCount:"+ count + '\nMessage' + e); } } var count = 0; var test1 = function(){ count = 0; var counter1 = function(){ count++; arguments.callee(); } (function(){ try { counter1(); } catch(e){ alert('Count:' + count + '\nMessage:' + e.message); } })(); } var test2 = function(){ count = 0; var counter2 = function(){ count++; counter2(); } window.counter2 = counter2; (function(){ try { counter2(); } catch(e){ alert('Count:' + count + '\nMessage:' + e.message); } })(); } </script> </head> <body onload="setup()"> Testing limit of recursion.<br /> <input type="button" value="Recursion by arguments.callee" onclick="test1();" /> <br /> <br /> <input type="button" value="Recursion by function name" onclick="test2();" /> </body> </html>
jsbinにテストページを作成しました
http://jsbin.com/ileju