apply の制限
- カテゴリ:
- JavaScript
- ブラウザ
- コメント数:
- Comments: 0
◆ apply で渡せる引数の数には制限あり
◆ 超えると statck サイズ超えのエラー (Chrome)
◆ 250000 くらい OK (Chrome)
◆ Firefox はちょうど 500000
◆ 直接書く引数のは 65535 まで (Chrome)
◆ 超えると statck サイズ超えのエラー (Chrome)
◆ 250000 くらい OK (Chrome)
◆ Firefox はちょうど 500000
◆ 直接書く引数のは 65535 まで (Chrome)
apply するときの引数の数
いきなりですがこういうコードを実行してみますfunction fn(){}
fn.apply(null, new Array(1000000))
fn.apply(null, new Array(1000000))
Uncaught RangeError: Maximum call stack size exceeded(…)
エラーです
しかもスタックサイズ超えだそうです
apply って中で再帰関数でも使ってるんでしょうか?
ES6 な方法にしてみます
function fn(){}
fn(...new Array(1000000))
fn(...new Array(1000000))
Uncaught RangeError: Maximum call stack size exceeded(…)
変わらずエラーです
普通に 関数呼び出しをカンマいっぱいで書いてみます
function fn(){}
fn(1,1,1,1,1,1,1,1,...,1,1,1)
fn(1,1,1,1,1,1,1,1,...,1,1,1)
Uncaught SyntaxError: Too many arguments in function call (only 65535 allowed)
65535 個以上の引数はダメみたいです
ということは apply も一緒なのかな?
function fn(){}
fn(...new Array(70000))
// undefined
fn(...new Array(70000))
// undefined
apply は 65535 が制限ではないみたいです
がんばって手動で apply の限界値を調べてみると だいたい 250000 ちょっとくらいでした
といっても環境によって変わります
同じブラウザでもバージョンや 同じバージョンでもインストールしてる PC とか実行しているページなどで変わるようです
いくつか試したところ 最近の Chrome 系ならだいたい 250000 くらいです
Firefox だと apply でも直接書いても
RangeError: too many function arguments
とメッセージがでした
apply の渡せる引数はちょうど 500000 まで OK でした
見つけたとき
ところで気づいたのは Uint8Array から base64 作ろうと String.fromCharCode に apply しようとしたときです数MB のファイルだったのでエラーになっていました
String.fromCharCode は渡した引数全部を文字にして結合した文字列が返って来ます
ですが こういう問題が起きるので一文字ずつ実行して自分で結合したほうが良さそうです
一文字ずつするにしても map は注意です
var u8A = new Uint8Array(100).fill(65)
console.log(u8A.map(e => String.fromCharCode(e)))
console.log(u8A.map(e => String.fromCharCode(e)))
[0, 0, 0, 0, 0, ........, 0, 0]
Uint8Array の map は Uint8Array になるので数字以外の文字列を入れると 0 になってしまいますArray.from で配列化してから map すれば大丈夫です