Есть идеи, почему у первого варианта в IE8 длина стека вызовов всего 5?
/**
* setImmediate polyfill
*/
window.setImmediate || new function () {
var id = 0, storage = {}, message = "setImmediatePolyfillMessage";
function fastApply(args) {
var func = args[0];
switch (args.length) {
case 1: return func();
case 2: return func(args[1]);
case 3: return func(args[1], args[2]);
}
return func.apply(window, Array.slice(args, 1));
}
function callback(event) {
var key, data;
event = event || window.event;
key = event.data;
if (typeof key == "string" && key.startsWith(message)) {
data = storage[key];
if (data) {
fastApply(data);
delete storage[key];
}
}
}
function setImmediate() {
var key = message + ++id;
storage[key] = arguments;
postMessage(key, "*");
return id;
}
function clearImmediate(id) {
delete storage[message + id];
}
addEventListener("message", callback, false);
window.setImmediate = setImmediate;
window.clearImmediate = setImmediate;
};
пробовал arguments преобразовывать в массив, не помогает, 6-й рекурсиный вызов приводит к stack overflow
/**
* IE8 setImmediate polyfill
*/
document instanceof Object || new function () {
var root = document.documentElement, fakeScript = document.createElement("script");
//todo code reuse
function fastApply(args) {
var func = args[0];
switch (args.length) {
case 1: return func();
case 2: return func(args[1]);
case 3: return func(args[1], args[2]);
}
return func.apply(window, Array.slice(args, 1));
}
function setImmediate () {
var args = arguments, tmpScript = fakeScript.cloneNode(false);
tmpScript.onreadystatechange = function () {
fastApply(args);
tmpScript.onreadystatechange = null;
root.removeChild(tmpScript);
tmpScript = null;
};
root.appendChild(tmpScript);
return 0;
}
function clearImmediate() {}
window.setImmediate = setImmediate;
window.clearImmediate = setImmediate;
};
а этот вариант нормально работает