My JavaScript book is out! Don't miss the opportunity to upgrade your beginner or average dev skills.

Friday, July 29, 2011

About JavaScript apply arguments limit

Just a quick one from ECMAScript ml ... it is true that browsers may have a limited number of arguments per function. This may be actually a problem, specially when we use apply to invoke a generic function that accepts arbitrary number of arguments.

String.fromCharCode

This is a classic example that could fail with truly big collection of char codes and here my suggestion to avoid such limit:

var fromCharCode = (function ($fromCharCode, MAX_LENGTH) {
// (C) WebReflection - DO THE FUCK YOU WANT LICENSE
return function fromCharCode(code) {
typeof code == "number" && (code = [code]);
for (var
result = [],
i = 0,
length = code.length;
i < length; i += MAX_LENGTH
) {
result.push($fromCharCode.apply(null, code.slice(i, i + MAX_LENGTH)));
}
return result.join("");
};
}(String.fromCharCode, 2048));

// example
alert(fromCharCode(80)); // P
alert(fromCharCode([80, 81, 82, 83, 84])); // PQRST

The revisited version accepts directly an array and performs the call ceil(codes.length / MAX_LENGTH) times.
Performances impact will be irrelevant while bigger Arrays will be parsed, hopefully, without problems.
If we still have problems we should never forget that userAgents may have a limited amount of available RAM so ... split the task or the operation or stream it.

As Summary

It's not that difficult to apply same concept with whatever function may suffer the apply and number of arguments limits: just define a maximum amount of arguments, in this case 2048, so that the task will be distributed without problems.

1 comment:

  1. Hi,

    I was just about to post this same answer. The expected result is different because String.fromCharCode constructs the returned string from all arguments passed in (in this case, the first 2 arguments passed in because the third isn't a number).

    regards,

    ReplyDelete

Note: Only a member of this blog may post a comment.