Показать сообщение отдельно
  #7 (permalink)  
Старый 30.03.2014, 04:11
Отправить личное сообщение для Octane Посмотреть профиль Найти все сообщения от Octane  
Регистрация: 10.07.2008
Сообщений: 3,873

Есть идеи, почему у первого варианта в 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;

};
а этот вариант нормально работает
Ответить с цитированием