JavaScript

индекс
246,38

Отладка Javascript

Debug Logo

Многие задают мне один и тот же вопрос:
«Как дебажить этот $%*!%$! Javascript?».

Так вот, во-первых Javascript — не $%*!%$! А как я его дебажу — сейчас расскажу.

(Примечание: наверное эта статья больше для новичков. Так что не судите строго)


Казалось бы — да что тут рассказывать? Всё же очевидно. Но вопрос этот мне задают с завидной частотой. Да и мне есть, что рассказать.

Приведу конкретные примеры и расскажу, как я их решаю.

Видим цель, не видим препятствий


Javascript вывалил ошибку? Замечательно! Нет, это конечно плохо, но гораздо лучше, чем если бы он промолчал (да, бывает и такое!) в случае ошибки.

Наша цель — понять, что же, чёрт побери, произошло? Но сначала — рекламная пауза лирическое отступление: средства Javascript Debug'а в основных браузерах.

Debuggers


Вот основные браузеры и их средства отладки:
  • Firefox Logo Firefox:
    Всеми нами любимый плагин Firebug
  • Safari Logo Safari, Chrome Logo Chrome:
    Встроенный в WebKit Web Inspector
  • Opera Logo Opera:
    Чудесный встроенный Dragonfly
  • IE Logo Internet Explorer 8:
    Встроенный Developer Tools
  • IE Logo Internet Explorer <= 7
    Тут есть множество вариантов:
    DebugBar, Companion.JS, через MS Visual Studio
    Но меня все эти штуки как-то не зацепили — все они либо громоздкие, либо неудобные, либо платные :)
    А зацепил меня только лишь script Debugger. Он очень спартанский, но в нём есть всё, что мне нужно.

Во всех этих средствах отладки нас будут интересовать breakpoint'ы:

Debuggers Screenshot 1

А вот немного «вкусностей» — conditional breakpoints (правый клик по «бряке»):

Debuggers Screenshot 2

То есть заводим глобальную переменную (к примеру) allowBreakpoints и «бряки» будут срабатывать только тогда, когда мы сами того захотим.
К сожалению, работает не везде, поэтому я это обычно не использую.

Как «тормознуть» поток


Ключевое слово debugger. Увидав такое в коде, любой уважающий себя JS-debugger остановит поток Javascript и покажет нам место остановки

Debugger Keyword Screenshot 1

Можно смело пользоваться в:
  • Firefox Logo Firefox со включенным Firebug'ом
  • Safari Logo Safari, Chrome Logo Chrome с открытым/включённым Web Inspector/script Panel
  • IE Logo Internet Explorer 8 с открытым/включённым Developer Tools
  • IE Logo Internet Explorer <= 7 с установленным script Debugger
  • Opera Logo Opera с открытым/включённым Dragonfly

И не бойтесь писать debugger в вашем коде — ошибки это нигде не вызовет.

А вот вариант с условной остановкой:
if (allowBreakpoints == true)
  debugger;


* This source code was highlighted with Source Code Highlighter.

Мне так нравится гораздо больше, чем ставить «бряку»: так я пишу код и дебажу его по сути в одном месте, а не в двух.

Debug через alert()


Это наименее информативный debug, который к тому же останавливает поток Javascript. Да к тому же модальный по отношению к браузеру. Забудьте, что он вообще существует.

Особенность breakpoint'ов


Рассмотренные варианты все, как один, тормозят поток Javascript. Это плохо!

Почему? Если в момент остановки скрипта у вас был запущен AJAX-запрос или Timeout, и ответ не успел вернутся — он может уже не вернутся никогда. Согласитесь, в современных web-проектах этого добра хватает. Поэтому в момент «экстренной остановки» скрипта мы уже не сможем адекватно debug'ать дальше — часть логики будет безвозвратно утеряна.

Поэтому я стараюсь избегать на практике debug с остановкой.

«Debugging Javascript with breakpoints is bad, mmkay?» © Mr. Mackey, South Park

Однако: breakpoint есть breakpoint, и если вы исследуете ну очень запущенный баг — тут без остановки не обойтись (надо будет сделать watch текущим переменным и т.д.)

«Правильный» debug


Коротко: хороший debug — через logging. Так я в основном и работаю — в нужном месте в нужное время срабатывает console.log(...).

Да, насчёт console.log — впервые этот метод увидел мир, насколько я помню, вместе с Firebug. Никакой это не стандарт и не факт, что оно заработает в IE6. Однако современные браузеры вводят logging именно как console.log. Это так, к сведению. И если в продакшн попадёт код с console.log(...) — будьте на чеку, может поломаться! Так что может быть стоит переопределить у себя в коде объект console, так, на всякий пожарный.

Если же в целевом браузере нет console.log, а хочется — попробуйте Firebug Lite или Blackbird, может понравится ;)

Пример №1


Javascript показал ошибку. Надо понять — что к чему.
Включаем в debugger'е режим «Break On Error»:



Воспроизводим ошибку снова. Javascript останавливается. Видим место ошибки, делаем watch и точно определяем, в чём же дело.

Пример №2


CASE:
Javascript не показал ошибку. Но вы знаете, что она есть (как суслик). Да, такое иногда бывает.

CASE:
Надо просто продебажить некий код. Скажем, посмотреть, что происходит по нажатию кнопки или после AJAX-загрузки данных.

Тут сложней — надо найти, с чего начать.

Немного искусства


Поиск «точки входа» Javascript'а — непростая штука. Вот как я это делаю:
  1. Самое главное — разбираться в средстве разработки. Будь то jQuery, или ExtJS, или Mootools, или вообще свой собственный framework — нужно понимать, как создаётся кнопка, как «навешивается» обработчик события, как данные ходят в AJAX, как попадают в grid, как работает TinyMCE RTE, как, как, как… Если нет понимания задачи — не получится её решить!
  2. Используем Inspect нашего debugger'а (если нет Inspect'а — используйте всё тот же Firebug Lite):
    1. Находим нужный элемент HTML (например, кнопку)
    2. Ищем ближайший от него элемент с осмысленным ID (н-р: id=«my-super-button»; а id=«ext-gen124» уже не подходит) вверх по иерархии (это может быть и сама кнопка, а может быть DIV четырмя уровнями выше)
  3. Ищём в нашем коде вхождение этого осмысленного ID'шника
  4. Нашли. Отлично, теперь вдумчиво читаем код и находим нужное место (обработчик нажатия кнопки, AJAX-запрос и т.д.)
  5. Пишем в нужном месте debugger:
    // условная остановка
    if (allowBreakpoints == true)
      debugger;

    // или просто
    debugger;

    * This source code was highlighted with Source Code Highlighter.
Конечно данный способ не идеален. Бывает, что даёт промашки. Но это хороший способ, мне он сильно помагает в работе.

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

Пример №3


Тот же случай: надо продебажить некий код. Скажем, посмотреть, что происходит по нажатию кнопки или после AJAX-загрузки данных. Но в этот раз мы не можем тормозить поток Javascript по описанным мной причинам.

Итак:
  1. Ищем нужное место тем же способом
  2. Вместо debugger пишем console.log(variable_to_watch)

Тут есть интересные модернизации.

CASE UNO


variable_to_watch — объект, который изменился с момента вывода в консоль. А хочется увидить его состояние именно на момент вызова.

Тут надо использовать не console.log(variable_to_watch), а console.dir(variable_to_watch)

CASE DUO


Нужно не просто увидеть текущее значение variable_to_watch, но ещё и поэкспериментировать с ним (например, хочется вызвать его метод):
// пусть хочется получить доступ к объекту obj
if (debugEnabled)
  console.log(window.temp_var = obj);

* This source code was highlighted with Source Code Highlighter.

Таким образом мы не только увидим вывод в консоли, но и получим доступ к объекту через глобальную ссылку на него: window.temp_var.

Открываем Firebug->Console и вызваем метод: temp_var.objMethod().

Нет консоли? Пишем в адресной строке: javascript:alert(temp_var.objMethod()); void 0;

Пример №4


Ещё один пример. Возможно, немного странный. Хочется продебажить метод 3d-party-framework'а (например, ExtJS), но вот беда — нельзя тормозить Javascript и нет доступа к исходному коду (правда странный пример? :)

Что же делать? Я делаю так:

Создаём файл с патчем: my-ext-patch.js, и подключаем его после ext-all.js
Внутри пишем что-то вроде:
(function() {
  var _backup = Ext.form.Form.render; // Резервируем метод рендера формы. -- Ваш Кэп ;)

  Ext.form.Form.render = function(container) { // Wrap'им метод
    // А вот и дебаг
    console.log(container);

    // Возможны варианты:
    // console.dir(container);
    // console.log(window.t = container);
    // debugger;

    // Выполняем начальный метод
    return _backup.apply(this, arguments);
  }
})();

* This source code was highlighted with Source Code Highlighter.

Извращение? Возможно. Но мне нравится >:)

Эпилог


Вот так можно дебажить «этот $%*!%$!» Javascript. Важно сосредоточиться на первых трёх примерах.

Надеюсь, что мой опыт кому-то поможет.
+164
26 ноября 2009, 17:26
425

комментарии (67)

+8
Etherial #
Несомненно поможет! Годная статья, в избранное :)
+1
DIDJER #
— «в избранное — непременно в избранное»
+1
alist #
Так на всякий случай добавлю, что для всех браузеров есть getfirebug.com/lite.html
Я его использую в Опере, если надо какие-то косяки с версткой поправить: просто кнопка inspect у него очень удобно расположена :)
0
uwl #
Пользуюсь подобным, для подключения firebug.lite.js на всех проектах, в независимости от браузера.

 if (typeof(console) != 'object') {
    var firebug = {env: {css : "PATH_TO_CSS/firebug-lite.css"}};

    var doc = window["document"]||null;
    var script = doc.createElement('script');
    script.setAttribute('type', 'text/javascript');
    script.setAttribute('src' , "PATH_TO_FIREBUGLITE/firebug-lite-compressed.js");
    doc.getElementsByTagName('head')[0].appendChild(script);
 }

+2
kivsiak #
Даже для не слишком новичка полезно прочитать.
0
aLexusPro #
После релиза все if (allow… удаляются или allow просто выставляется в false?

В целом спасибо, было интересно.
0
Kottenator #
Извиняюсь, промахнулся. Ответ на ваш вопрос — чуть ниже
0
Ikari #
Спасибо, полезная статья.
0
akira #
Человек! Человечище! Спасибо!
За отладку в IE отдельно спасибо!
+1
AleksDesker #
Спасибо за статью, вы возвращаете мою веру в хабр :)
+1
web4_0 #
А меня Debug Bar зацепил больше, чем IE8 Developer panel. Последняя тормозит у меня.
Ну и недавно обсуждавшаяся DynaTrace AJAX toolbar тоже очень полезная штука.

А статья шикарная.
0
Kottenator #
Вообще можно и оставить. Только я написал allowBreakpoints, что есть не очень хорошо. Лучше эту переменную не помещать в глобальный scope, а создать свой небольшой а-ля namespace (который будет подключаться на каждую страницу сайта):
var MyTools = {
    debug: {
      isOn: false
    }
}
// ...
// где-то в коде:
if (MyTools.debug.isOn)
    console.log(some_var)

* This source code was highlighted with Source Code Highlighter.

А ещё можно обернуть console.log своим методом:
var MyTools = {
    debug: {
        isOn: false,
        log: function() {
            if (this.isOn && window.console)
                console.log.apply(console, arguments);
        },
        stop: function() {
            if (this.isOn)
                debugger;
        }
    }
};
// ...
// где-то в коде:
MyTools.debug.log(some_var);
MyTools.debug.stop();

* This source code was highlighted with Source Code Highlighter.
0
Kottenator #
Прошу прощения, это был ответ на коммент, я промахнулся
НЛО прилетело и опубликовало эту надпись здесь
+2
Kottenator #
sedoy, зачем убиваешь себя?
0
Violinist #
console.log вылетает в IE любой версии, в Chrome, firefox — нет (ну это касается продакшн).
+1
ya_goshka #
для ие можно сделать свой лог)

if(!window.console)
{
console = {};
console.log = function(message){alert('Консоль говорит: \n\n' + message)};
}
+1
ya_goshka #
или выводить все в какой-нибудь элемент в dom
+1
Kottenator #
Да, я упомянал в статье Firebug Lite или Blackbird

В обоих вариантах — вывод в какой-то ДОМ-элемент

И потом это прикрутить вот сюда — вот и получится универсальный логгер с флажком! :)
0
Violinist #
конечно можно, я просто добавил уточнение про то, что будет если его не убрать в продакшн
0
ya_goshka #
для продакшена можно просто переопределить console для всех браузеров
0
gbezyuk #
Я в своих проектах с целью недопущения logging'а до продакшна использую следующий код, возможно он будет интересен или полезен:
ProjectNamespace.log = function ()
{
if (! ProjectNamespace.MUTED_CONSOLE
&& typeof(console) != 'undefined'
&& typeof(console.log) == 'function')
{
console.log.apply(null, arguments);
}
};
}

Соответственно, при необходимости дебага вызывается ProjectNamespace.log() вместо console.log, и на продакшне ProjectNamespace.MUTED_CONSOLE ставится в true.
Если есть сторонний код, из которого вызывается console.log напрямую, или же просто не хочется изменять своим привычкам, то для безопасности продакшна можно сделать следующий финт ушами:

ProjectNamespace.originalConsole = console;
ProjectNamespace.log = function ()
{
if (! ProjectNamespace.MUTED_CONSOLE
&& typeof(ProjectNamespace.originalConsole) != 'undefined'
&& typeof(ProjectNamespace.originalConsole.log) == 'function')
{
ProjectNamespace.originalConsole.log.apply(null, arguments);
}
};
}

console.log = ProjectNamespace.log;
0
immaculate #
У меня в Safari под Windows при остановке на breakpoint, в окне пропадает исходник Javascript. То есть можно жать кнопки пошагового прохода, справа меняется номер строки и значения переменных, но вместо когда — пустой прямоугольник. Пришлось искать ошибку другим способом. Safari вроде последний, 4.0.4.

Собственно, Safari был нужен только потому, что пользователь Safari жаловался, что у него не работает сайт.
–2
koriza #
Лучший дебаггер для javascript — это понимание того, как устроен javascript (а не только библиотеки), и в первую очередь, наверное, замыкания.
0
Kottenator #
Да, тут без понимания и шага не сделаешь.

Но когда перед тобой огромный проект, с нескольколетней историей разработки и сотней тысяч строк — тут без дебага не обойтись
0
gbezyuk #
Это условие почти всегда необходимое, но довольно редко достаточное для оперативного решения задач отладки.
0
webwin #
если нужно посмотреть значение объектов, можно использовать
console.log('%o',obj)
Аякс запросы (какие данные передали, какому скрипту, что вернул скрипт) кроме как в firebug можно просматривать?
+1
Kottenator #
Firebug
Opera Dragonfly -> Network Tab = показывает AJAX
Safari/Chrome WebInspector -> Resources Tab = показывает AJAX
IE — я не нашёл. Но можно поставить себе на комп что-то типа Fiddler, тогда и с IE разберёмся :)
0
webwin #
Спасибо. Глаза открыли)
Сафари/Хром показывают что вернул скрипт, Opera Dragonfly — нет, но и знать какой скрипт запрашивается очень помогает
0
burivuh #
Для IE есть неплохой плагинчик HTTP Analyzer
0
choor #
Для аякса есть прекрасный плагин HTTPWatch под Internet Explorer, вообще мощная утилита.
Аналог у Firefox это HTTPFox

P.S. Утилиты не только для Аякса, отнюдь, снифает весь трафик.
0
taliban #
alert — очень хорошо, если нужно посмотреть информацию которую можно увидеть через алерт, то следует использовать именно его, метки дебага — отлично и удобно, но они пассвино заставляют забывать дебаги в коде, а со временем еще и специально оставлять, мозг сам аргументирует: «не влияет на работу, ну и оставим, на всякий случай» в итоге получаем в релизе кучу инфы для дебага, помоему это плохо
+1
ELV1S #
Я сделал console.js. Это скрипт-прокладка для API консоли Firebug-а. Полезен для Оперы и IE. Умеет «разворачивать» объекты, в отличие от alert-а и opera.postError.

alert({x:3, y:5}) --> [object Object]
alert(document.body) --> [object HTMLBodyElement]

console.log({x:3, y:5}) --> { 'x': 3, 'y': 5 }
console.log(document.body) --> <BODY class="timeline" id="home">
0
webwin #
В ie8 выдает ошибку Объект не поддерживает это свойство или метод console.group(«basic arrays and objects»);
в opera 10.00 не вижу что бы что-то писалось в лог
в хроме 3.0.195.33 только надписи object
0
ELV1S #
В IE8 и Хроме этот скрипт ничего не делает. Первая строчка скрипта: if (typeof console === 'undefined') {, а там консоль определена.

В IE8 нету console.group. Получается ошибка. Исправлю как-нибудь.

В Опере у меня работает нормально.

В Хроме 4 должно быть как на скриншоте. Не знаю как в 3-й, меня она мало интересует.

0
xxxYURAxxx #
можно вопрос? а то мне всегда было интересно как люди выкручиваются :)
как вы выбираетесь из ситуации, когда надо узнать, какие обработчики висят на элементе?
если есть элемент с несколькими классами, на каждый из которых есть свой обработчик.
+5
ELV1S #
0
homm #
Отличная штука, тоже рекомендую.
+2
ELV1S #
0
homm #
Recommended Configuration
Firefox 3.7a1pre
Firebug 1.5b1
Eventbug 0.1a2
Не слабо.
+1
ELV1S #
Только в 3.7 появился getListenerInfoFor. До этого не было никакого механизма для просмотра событий.
+1
goshi #
все методы console кому интересно: getfirebug.com/console.html
+2
sir_Jack #
Отличная статья, наконец-то узнал как ошибки в скриптах вылавливать… :) а то все по методу черного ящика кодил… :)
+1
webwin #
+ отличные комментарии
0
try4tune #
В Опере так и не смог толком подебажить.
0
Flcn #
Debug через alert()
«Это наименее информативный debug, который к тому же останавливает поток Javascript. Да к тому же модальный по отношению к браузеру. Забудьте, что он вообще существует.»

БРЕД.
кучу раз встречал случай когда алерт лучшее решение (в том числе так как он останавливает исполнение)
плюс дебаггеры очеь плохо относятся к подгружаемому eval коду который ещё и меняется постоянно…
0
Kottenator #
Может быть это моё личное мнение, но когда, когда alert() лучше, чем приведённые мной способы (breakpoints, debugger, console.log/dir, ...)?

Ведь alert останавливает поток, блокирует взаимодействие с браузером и при этом всего навсего выводит строку… Без возможности заглянуть в иерархию объекта.

breakpoints тоже тормозят поток, но при этом дают возможность осмотреться в scope. И не модальный.
console.log/dir — не тормозит поток, но более информативен, т.к. даёт заглянуть внутрь объекта. И не модальный.

Чем же alert() лучше?
0
Apocalepse #
Спасибо, полезная статья!
0
ferrari #
Как сказано автором, действительно очень просто забыть console.log в коде, ловился на этом и было не очень приятно за такую детскую ошибку, в каждом проекте есть функция-синоним вида function c(x){ try{console.log(x); }catch{} }. и пользоваться быстрее с(yourElement) и IE не падает.
0
kulakowka #
статья очень порадовала. Нашел для себя парочку новых способов.

Но вот что действительно интересует. Как отладить баг, если во всех браузерах работает, а в IE 7 не пупыжит :( ???
0
ya_goshka #
смотреть на каком месте пупыжит и читать мсдн про это
+2
homm #
Отлаживайте в ие8 в режие ие7.
0
Kottenator #
Как вариант:
поставить в IE7 script Debugger + Firebug Lite. Ну и + хорошее знание JS и проекта :)
0
kpower #
Внесу свою посильную лепту.

Когда дебажим под IE8. Во встроенном Developer Tools есть переключатель режима обозревателя: ie7, ie8, представление совместимости ie8. Кроме того, можно изменять и режим документов: стандарты ie7, стандарты ie8 и режим совместимости, он же quirks mode. Исходя из понимания последнего названия, данный режим заставляет браузер работать, учитывая «особенности и ошибки конкурирующих или старых версий программных продуктов» (с, Википедия) — в общем, с намеком на ie6 и ко.
Не могу со 100% вероятностью сказать, насколько точно ie7-режимы совпадают с реальностью. Однако эмпирически было проверено, что после корректного отображения в этом режиме, реальный ie7 показал корректно. quirks mode особо не использовал.

И еще момент. Вряд ли кому открою Америку, но сам почему-то не сразу догадался до подобного. В общем, часто встает необходимость вывести дебаг в формате: метка + значение. Причем значение может быть объектом. Конечно, можно выводить в разных строках, но тогда при больших объемах лога становится трудно разбирать что и где (как минимум не наглядно). Вариант решения: console.log([ label, value ]); — соответственно будет и метка, и значение. Плюс возможность сразу просмотреть объект (в том же firebug). Как вариант, можно обернуть в {} — для массового вывода ;)
0
Dolios #
В console.log можно написать, например, так:

console.log(label, value, label, value, value, value);

И все будет прекрасно выводиться и не нужно оборачивать ничего.
НЛО прилетело и опубликовало эту надпись здесь
0
burivuh #
Возможно кому-то поможет:

Иногда необходимо вывести в лог свой объект со всеми свойствами, или в alert, чтобы посмотреть что-то по-быстрому. Для приведения объекта к строке браузеры вызывают ему toString(). Этот метод определен в основных типах (типа Object, Function и т.д.). Однако, приведение объекта к строке по-умолчанию возвращает [object Object].

Идея в том, чтобы в своих объектах перегрузить метод toString, чтобы выводить что-нибудь полезное. Например так:

var MyObj = {
	property1 : "qwerty",
	property2 : 100500,
	anotherProperty : true,
	method1 : function() {
		// do something
	},
	toString : function() {
		return "{\n" + 
		"  property1 : " + this.property1 + ",\n" + 
		"  property2 : " + this.property2 + ",\n" + 
		"  anotherProperty : " + this.anotherProperty + "\n" +
		"}";		
	}
};


Теперь вызов alert(MyObj) будет выводить не [object Object], а все свойства объекта:

{
  property1 : qwerty,
  property2 : 100500,
  anotherProperty : true
}
0
burivuh #
Продолжая мысль… не обязательно держать определение объекта и его toString вместе.
Можно написать в продакшн коде:
var MyObj = {
	property1 : "qwerty",
	property2 : 100500,
	anotherProperty : true,
	method1 : function() {
		// do something
	}
};


А в отдельном файле (например, debug.js) написать следующее:

if(MyObj)
{
	MyObj.toString = function() {
		return "{\n" + 
		"  property1 : " + this.property1 + ",\n" + 
		"  property2 : " + this.property2 + ",\n" + 
		"  anotherProperty : " + this.anotherProperty + "\n" +
		"}";		
	}
}


И подключать его по мере надобности, т.е. во время разработки
0
kpower #
Еще как вариант — написать общую функцию, где for (var i in object)… вывести поля. можно рекурсивно — тогда не придется заморачиваться под каждый новый объект.
0
burivuh #
Тоже вариант, но тогда будет меньше контроля над тем, как отображать содержимое.
Тут уже каждый решает в каждом конкретном случае, что лучше )
0
Kottenator #
Продолжу мысль:

  • -> переопределить toString
  • -> вынести toString и применять к любому объекту
  • ->сделать рекурсивный пробег по иерархии объекта (попутно избежав бесконечной рекурсии)
  • -> сделать красивый вывод иерархии объекта (с "±" и т.д.) в какой-нибудь DIV коммандой console.log(obj)
  • -> чёрт, это всё уже сделано в Firebug Lite! :) Скачать, пользоваться на здоровье :)


Понимать, как это работает — здорово. Но надо экономить своё время и уметь полагаться на 3d-party разработки ;)
0
dsCode #
> -> переопределить toString

Не стоит. Object.prototype.toString — особенный ;)
0
afelya #
Отличная статья, спасибо!
0
heel #
Может кому-то еще пригодится: Продвинутая отладка Javascript
0
CestLaVie #
Спасибо! Неплохая статья — я не слышал про дебаг для Opera`ы и Safari/Chrome — так что нашёл ссылки довольно ценными.

Маленькое дополнение — есть, на мой взгляд, отличный проект Log4Javascript ( log4javascript.org/ ), который достоин, на мой взгляд, упоминания в этой статье — он позволяет упростить кроссбраузерный логгинг. Идея взята из мира Java — его прототипом выступил очень известный там проект Log4J.

Я стараюсь его использовать и советую всем, кто разрабатывает серьёзные проекты с активным использованием JS к нему присмотреться.
0
shx #
Отличный пример грамотно написаной статьи. Не напрягая мозги все понял.
0
kellas #
Удобно включать режим отладки из адресной строки, например дописывая в неё #console

if(typeof allow_console == 'undefined'){
   var allow_console= false;

   var hash = location.hash;
   if(hash.indexOf('#console')!=-1){
     allow_console = true;
   }
}
if(allow_console==true){
console.log('Режим отладки включен');
}

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.