Как получить вызовы функции Javascript/трассировка во время выполнения
Когда я взаимодействую с моим приложением на основе AJAX на RUNTIME, я бы хотел, чтобы консоль выдала все функции, которые он вызывает. (так что нет трассировки стека, точек останова или профилирования или чего-либо еще)
Итак, скажем, я нажал кнопку на странице. Я бы хотел, чтобы он возвращал все функции
прошло, когда это произошло:
Итак, я видел в консоли что-то вроде (когда я нажимал кнопку):
1. button1Clicked();
2. calculating();
3. printingResults();
Что в основном означает, что button1Clicked() вызвал вычисление(), которое вызвало printingResults()
Есть ли утилита или плагин, браузер или, может быть, какой-то способ на этом языке? Я использую google chrome, btw.
p.s и NO Я не хочу проходить через каждую функцию и добавлять "console.log("inside function X")"
b/c, что слишком много работает
p.p.s в качестве дополнительного бонуса, я бы тоже хотел увидеть аргументы, передаваемые в функции, но, возможно, это нажатие.: >
Ответы
Ответ 1
Я не могу придумать отличный способ перехватить все вызовы функций глобально, чтобы вставить ведение журнала (хотя в разделе обновления есть подходящее обходное решение).
Вместо этого, как насчет только добавления ведения журнала к функциям в определенном пространстве имен, которое вас волнует? Вы можете сделать это со следующим установочным кодом:
var functionLogger = {};
functionLogger.log = true;//Set this to false to disable logging
/**
* Gets a function that when called will log information about itself if logging is turned on.
*
* @param func The function to add logging to.
* @param name The name of the function.
*
* @return A function that will perform logging and then call the function.
*/
functionLogger.getLoggableFunction = function(func, name) {
return function() {
if (functionLogger.log) {
var logText = name + '(';
for (var i = 0; i < arguments.length; i++) {
if (i > 0) {
logText += ', ';
}
logText += arguments[i];
}
logText += ');';
console.log(logText);
}
return func.apply(this, arguments);
}
};
/**
* After this is called, all direct children of the provided namespace object that are
* functions will log their name as well as the values of the parameters passed in.
*
* @param namespaceObject The object whose child functions you'd like to add logging to.
*/
functionLogger.addLoggingToNamespace = function(namespaceObject){
for(var name in namespaceObject){
var potentialFunction = namespaceObject[name];
if(Object.prototype.toString.call(potentialFunction) === '[object Function]'){
namespaceObject[name] = functionLogger.getLoggableFunction(potentialFunction, name);
}
}
};
Затем для любого объекта namespaceObject, к которому вы хотите добавить запись, вы просто вызываете:
functionLogger.addLoggingToNamespace(yourNamespaceObject);
Здесь скрипка, чтобы увидеть ее в действии.
UPDATE
Обратите внимание, что вы можете вызвать functionLogger.addLoggingToNamespace(window);
, чтобы добавить журнал во все глобальные функции во время вызова. Кроме того, если вы действительно хотите, вы можете пройти дерево, чтобы найти какие-либо функции и соответствующим образом обновить их. Единственным недостатком этого метода является то, что он работает только с функциями, которые существуют в то время. Таким образом, это все еще не самое большое решение, но это намного меньше, чем добавление записей вручную:)
Ответ 2
Это называется профилированием, а Chrome и Firebug встроены. В Инструменты разработчика Chrome перейдите на вкладку профилей и нажмите запись ( круг). Выполните свой аякс и после вашего ответа нажмите кнопку записи еще раз, чтобы остановить. Результаты профилирования появятся в правой панели.
Обратите внимание, что это даст вам все, поэтому, если вы используете библиотеку jQuery, подавляющее большинство вызовов функций будет для вас мусором. Я пробовал это несколько раз, и я считаю, что сделать console.log('inside <method>')
гораздо полезнее.
Ответ 3
Попробуйте diyism_trace_for_javascript.htm:
https://code.google.com/p/diyism-trace/downloads/list
eval('window.c=function(){3+5;}');
declare_ticks_for(window);
function a(k, c) {
return k + 2;
}
function b() {
4 + 3;
a(3, {'a':'c','b':'d'});
c();
return 5 + 4;
}
b();
Просмотр журналов на вкладке консоли хром или firefox
Ответ 4
Возможно, у вас есть JavaScript, который может выполнить некоторые действия по добавлению console.log для вас:
Автоматическое добавление console.log для каждой функции
Также этот блог Paul Irish может помочь:
http://paulirish.com/2009/log-a-lightweight-wrapper-for-consolelog/
Он включает ссылку на какой-то JavaScript, специально предназначенный для протоколирования аргументов:
http://pastie.org/1033665
Ответ 5
Вариант решения Briguy37, я написал тот, который принимает функцию для вызова перед каждым методом. Он также работает с классами ECMAScript 6, где методы не перечислены для... in. Я использую его для изменения прототипов объекта, чтобы добавить ведение журнала ко всем новым экземплярам моего объекта.
function inject(obj, beforeFn) {
for (let propName of Object.getOwnPropertyNames(obj)) {
let prop = obj[propName];
if (Object.prototype.toString.call(prop) === '[object Function]') {
obj[propName] = (function(fnName) {
return function() {
beforeFn.call(this, fnName, arguments);
return prop.apply(this, arguments);
}
})(propName);
}
}
}
function logFnCall(name, args) {
let s = name + '(';
for (let i = 0; i < args.length; i++) {
if (i > 0)
s += ', ';
s += String(args[i]);
}
s += ')';
console.log(s);
}
inject(Foo.prototype, logFnCall);
Ответ 6
Я использовал решение @Briguy37 с улучшением. В моем случае я не хотел отслеживать функции из некоторых библиотек, поэтому я добавил код, чтобы их исключить. Вот как он используется:
- Сначала включите определение функций, которые вы не хотите отслеживать;
- excludeLoggingToNamespace, чтобы перечислять функции, определенные до сих пор, и исключать их;
- Включить определение функций, которые вы хотите отслеживать;
- Вызовите addLoggingToNamespace, чтобы добавить возможности ведения журнала к функциям, определенным на предыдущем шаге.
Пример:
<script src="js/someLibrary.js"></script>
<script>
functionLogger.excludeLoggingToNamespace(window);
</script>
<script src="js/codeIWantToTraceHere.js"></script>
<script>
functionLogger.addLoggingToNamespace(window);
</script>
Вот код, который я добавил в решение @Briguy37:
var excludedFunctions = {};
functionLogger.excludeLoggingToNamespace = function(namespaceObject){
for(var name in namespaceObject){
var potentialFunction = namespaceObject[name];
if(Object.prototype.toString.call(potentialFunction) === '[object Function]') {
excludedFunctions[name] = name;
}
}
};
И мне пришлось модифицировать метод @Bigigy37 addLoggingToNamespace, чтобы принять хэш хэш excludedFunctions:
functionLogger.addLoggingToNamespace = function(namespaceObject){
for(var name in namespaceObject){
var potentialFunction = namespaceObject[name];
if(Object.prototype.toString.call(potentialFunction) === '[object Function]' &&
!excludedFunctions[name]) {
namespaceObject[name] = functionLogger.getLoggableFunction(potentialFunction, name);
}
}
};