Pull to refresh

Функция К.O'Nsole.log для отладки в разных браузерах

Reading time5 min
Views2K
Хорош console.log, а нахваливать дальше некуда. И поддерживается не везде, и многобуквием страдает. И появляется задача иметь несложную функцию, настолько же гибкую, как console.log (или более), но приспособленную к разным браузерам без переделок, чтобы вывести одно или несколько значений. В отладке часто нужны текстовые поясняющие заголовки в строке, поэтому оказалось удобным иметь метод, добавленный к строке (объект String) с именем Alert, выполняющий то же самое, что и console.log и выводящий контекст-строку впереди списка аргументов. (Строку в апострофах, потому что удобно затем копировать и искать по кодам, где такой заголовок написан.)

Углубляться в многообразие команд в реализациях каждого браузера оказывается ненужным, потому что это теряет смысл при проверках в другом браузере. А долгое допиливание идеального продукта — попросту невыгодно, требует профессионального углубления в особенности и слежения затем за новинками, ошибками и их устранением. Нужна совершенно простая схема работы, которая легко доработается, если что-либо надо дополнительно и использующая базовые возможности консолей отладки.

Система чуть сложнее, чем доопределение самого console.log (внутренняя функция alertInner), и имеет такие достоинства:
1) новых слов всего 2, и те — знакомы;
2) слова — короче, чем К.О'Ns… (и т.д.);
3) не замещает других используемых имён,
4) гораздо проще других сложных скриптов,
5) код легко читается и кастомизируется.

Обычный alert() в этой системе участвует как наихудшая альтернатива вывода. Но и он может за один раз выдать несколько значений, разделённых запятой (например, в IE8 без включённого DebugBar-а).

Часто требуются 2 основных действия: запретить всю отладку одной командой; отключить бОльшую часть отладки, если вынужден смотреть алерты в малых объёмах или просто есть желание посмотреть часть сообщений. Строки-контексты для этого хорошо подходят. Будем включать только те сообщения, в заголовках которых найдутся образцы (жадного) регулярного выражения:

Alert.go =''; //- разрешить все; аналог типичного DEBUG = true; , но без лишней переменной;
Alert.go ='.'; //- разрешить только методы-Алерты, кроме ''.Alert() (простые функции Alert запрещены искусственно по признаку - так удобно, исключение 1);
Alert.go ='.*'; //разрешить и с пустой строкой, но без простых алертов, исключение 2;
delete Alert.go; //- запретить все;
Alert.go ='fthghhfgh'; //запретить методы-Алерты;
Alert.go ='^(aab|xaa==|test45:|xxx|__)$'; //- выполнять только перечисленное (и функции-Алерты).
 
(Для удобства в код вшиты 2 исключения и 1 кастомизация. Последнюю можно выбросить или наоборот, развить, но исключения — полезные и понятные. Надо иметь весь спектр действий: запретить всё, разрешить функции, разрешить методы, разрешить то и другое, разрешать методы с фильтром и без — не увеличивая систему команд.)

Запускаем:
Alert(aaa, bbb,'==переменные==', ссс); //обычный аналог console.log()
'xaa=='.Alert(xaa, xx.element, xaa(1)); //всё, что хотим - под своим заголовком в начале строки
'-test-'.Alert('вывод текста самого себя, например', Alert);

Таким образом, запускать на разных отладочных страницах разные выдачи оказывается удобно и наглядно. Инструмент остаётся крайне простым (всего 3 функции под одним именем, каждая из которых знакома и востребована), хотя есть резервы повышения монстрообразности — если в контекст ставить имя функции-обработчика или хеш, описывающий таблицу выдачи, можно далеко зайти. Или, например, я добавил в код ососбый вывод для сообщений вида Alert({from:'-test-', xx: прочие параметры… });. Обычно этот формат не нужен, т.к. забывается; но плюс его в том, что первый аргумент, хеш — просматривается разобранным, иногда бывает нужен для показа в простых алертах и в HTML.

Такую же систему сообщений можно внедрить в рабочий проект как приложение для других событий, под другим именем и выдавать не в консоль, а в хорошо оформленный блок, если они — для пользователя, или передавать на сервер.

Для консоли раньше в Опере нужно было так, сейчас не обязательно (есть Dragonfly-консоль, Ctrl-Shift-I, затем значок ">_"):
...else if (window.opera && opera.postError) {opera.postError(arguments);}

… Недавно тут FF5 (или firebug?) испортил картину, отказавшись понимать console.log.apply, пришлось дописать некрасивую альтернативу. Как обойти баг, не придумал, да и не обязательно. Редко число аргументов больше 7 и всегда их можно собрать в массив.

Код функции:
/**
 * Функция/метод "Лог-отладка-фильтр", spmbt0, 30.07.2011
 * @context (String) : начальные слова, описывающие строку отладки
 * @property go: рег.выражение для фильтра лога или undefined, если запретить выдачу
 * @param o: аргументы, выводящиеся в 1 строке в консоли отладки
 */
Alert = function(o){
	if(Alert.go===undefined) return; //===быстрый общий запрет===

	var alertInner = function(x, xx,a,b,c,d,e){ //x: аргументы (в FF5 - до 7, особенность Firebug для этой версии)
		var aL = arguments.length;
		if(!window.console){
			for(var i =0, args =[]; i < aL; i++)
				args[i] = arguments[i];
			alert(args);
		}else if(console.log.apply)
			console.log.apply(console, arguments);
		else{ //иначе - 5-й FF не умеет понимать console.log.apply
			if(aL ==1) console.log(x);
			else if(aL ==2) console.log(x, xx);
			else if(aL ==3) console.log(x, xx, a);
			else if(aL ==4) console.log(x, xx, a, b);
			else console.log(x, xx, a, b, c, d, e);
		}
	}, hasContext = this !== window
		, context = this;
	if(hasContext && context instanceof String){
		if(!RegExp(Alert.go,'g').test(context)) //===фильтрация по разрешениям===
			return;
		
		for(var i =1, args =[]; i <= arguments.length; i++)
			args[i] = arguments[i -1];
		args[0] = "'"+ context +"':";
		alertInner.apply(window, args); //===console.log с текстовым контекстом на первом месте===

	}else{ //место для кастомизации. Пример с {from:'имя', ...}
		if(Alert.go =='.' || Alert.go =='.*') return; //===запретить обычные алерты===
		if(o && o.from && o.from !=''){ //если в хеше в первом аргументе есть ключ "from", он оформляется особо
			var args =[], j =1;
			for(var i in o)
				if(i !='from'){
					args[j++] = '{'+ i +'}';
					args[j++] = o[i];
				}
			if(arguments.length >1) //разделитель
				args[j++] ='}; ';
			for(var i = 1, aL = arguments.length; i < aL; i++) //вывод следующих аргументов
				args[j++] = arguments[i];
			args[0] = "'"+ o.from +"':";
			alertInner.apply(window, args); //===console.log со значение ключа "from" на первом месте===

		}else
			alertInner.apply(window, arguments); //===обычный console.log===
	}
}
String.prototype.Alert = Alert;
Alert.go =''; //разрешить всё
//Alert.go ='test-'; //разрешить только с таким фрагментом в контексте (и все простые Alert() )
Для просмотра получившегося содержимого в консоли — сделать:
Firefox: при наличии Firebug — Ctrl-Shift-L (командная строка); без него — никто не знает :);
Chrome: Ctrl-Shift-J (консоль Javascript);
Safari: Ctrl-Alt-C (консоль ошибок);
IE: чтобы не выводилось это алертами, открыть DebugBar или что-то аналогичное;
Opera: сообщения видны в консоли ошибок (Ctrl-Shift-O), но там — с мусором; удобнее — в Dragonfly (Ctrl-Shift-I, затем значок ">_").

Работу скрипта с примерами смотреть здесь: spmbt.kodingen.com/function/testAlert.htm.



Вопрос (опрос): кто какие немонстровидные решения для отладки использует?

*) К литературе от себя добавлю, что есть у Firebug фича, которую крайне сложно найти в описаниях, если не знаешь, как она называется. Называется она "debugger;". Если такое имя встретится в джаваскрипте, Firebug остановится как на обычном брейкпойнте, дальнейший старт программы — из вкладки «Script» кликом на «Continue (F8)».
weirdan написал: --Эта фича есть в ECMA-262-5 и поддерживается как в Fx, так и в IE.

0. Firebug Command Line API.
0.1 Вышел релиз Firebug 1.8 (поддерживается в Firefox 5.0). Детальная информация (на Хабре) по новым возможностям версии.

О консоли на Хабре:
1. «Отладка Javascript в различных браузерах и средах», 24 января 2009, lomaster
2. Используем console на полную, 26 февраля 2011, Ryan Seddon
3. Удалённая отладка Javascript, 3 марта 2011, youtu.be…
4. Современная отладка JavaScript, 7 февраля 2009, Chris Mills, Hallvor…
5. Использование средств отладки, 27 августа 2008, Pamela Fox, Google M…
Tags:
Hubs:
+11
Comments16

Articles