39

RUNTIMEで AJAX ベースのアプリケーションと対話するときに、コンソールが呼び出しているすべての関数を吐き出すようにしたいと考えています。(つまり、スタック トレース、ブレークポイント、プロファイリングなどはありません)

たとえば、ページ上のボタンを押したとします。それが起こったときに通過したすべての関数を返すようにしたいと思います:

したがって、コンソールに次のようなものが表示されます(ボタンを押したとき):

1. button1Clicked();
2.     calculating();
3.          printingResults();

これは基本的に、button1Clicked() が calculate() を呼び出し、printResults() を呼び出したことを意味します。

これを行うためのユーティリティ、プラグイン、ブラウザ、または言語の何らかの方法はありますか? ところで、私はグーグルクロームを使用しています。

"console.log("inside function X")"ps といいえ私は各関数を実行して、あまりにも多くの作業を行う b/c を追加したくありません

追加のボーナスとして pps 関数に渡される引数も見たいのですが、それが押し付けているのかもしれません。:>

4

9 に答える 9

39

すべての関数呼び出しをグローバルにインターセプトしてログを挿入する優れた方法は思いつきません (ただし、以下の更新セクションに適切な回避策があります)。

代わりに、関心のある特定の名前空間内の関数にのみログを追加するのはどうですか? これは、次のセットアップ コードで実行できます。

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);
        }
    }
};

次に、ロギングを追加したい名前空間オブジェクトに対して、次のように呼び出します。

functionLogger.addLoggingToNamespace(yourNamespaceObject);

これが実際に動作していることを確認するためのフィドルです。

UPDATEを呼び出して、呼び出し時にすべてのグローバル関数にロギングを追加
できることに注意してください。functionLogger.addLoggingToNamespace(window);また、本当に必要な場合は、ツリーを走査して関数を見つけ、それに応じて更新することもできます。この方法の欠点の 1 つは、その時点で存在する関数に対してのみ機能することです。したがって、これはまだ最善の解決策ではありませんが、手動でログ ステートメントを追加するよりもはるかに少ない作業です :)

于 2012-08-07T21:05:23.593 に答える
17

これはプロファイリングと呼ばれ、ChromeとFirebugには組み込まれています。Chromeデベロッパーツールで、[プロファイル]タブに移動し、[記録(丸)]ボタンをクリックします。ajaxを実行し、応答後、録音ボタンをもう一度クリックして停止します。プロファイリングの結果が右側のペインに表示されます。

これですべてが得られることに注意してください。jQueryのようなライブラリを使用している場合、関数呼び出しの大部分はごみになります。私はこれを数回試しましたが、それを行う方がはるかに役立つことがわかりましたconsole.log('inside <method>')

于 2012-08-07T20:21:58.020 に答える
3

おそらく、console.log を追加する作業の一部を JavaScript に実行させることができます。

すべての関数に console.log を自動的に追加する

また、ポール・アイリッシュによるこのブログも役立つかもしれません:

http://paulirish.com/2009/log-a-lightweight-wrapper-for-consolelog/

これには、特にロギング引数を対象としたいくつかの JavaScript へのリンクが含まれています。

http://pastie.org/1033665

于 2012-08-07T21:20:47.790 に答える
3

Briguy37 のソリューションのバリエーションとして、各メソッドの前に呼び出す関数を受け入れるものを作成しました。また、メソッドが for...in によって列挙されない ECMAScript 6 クラスでも動作します。オブジェクトのプロトタイプを変更し、オブジェクトのすべての新しいインスタンスにログを追加するために使用しています。

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);
于 2016-07-26T05:01:25.353 に答える
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();

Chrome または firefox のコンソール タブでログを表示する

于 2013-01-17T10:18:49.310 に答える
1

リングに 3 番目の (確かに多少不完全な) ソリューションを投入させてください。

他のすべての回答は、2 種類の解決策を提供することに注意してください。

  1. 実行時に JS 関数に手動でパッチを適用し、コンソールにログを記録する
    • はい、それは仕事を成し遂げることができますが、プロジェクトが特定のサイズに成長すると役に立たなくなります. この機能の削除に時間を費やし続けない限り、十分な制御性は得られません。
  2. Jeff は、デバッグ目的でプロファイラーを使用することを提案しています
    • プロファイラー ビュー (少なくとも今のところ) は、コール グラフではなく、パフォーマンスの分析に役立つように設計されているため、あまり役に立ちません。非生産的なユーザー インターフェイスに慣れるために多くの時間を費やさない限り、うまく機能しません。

そのため、進行中の作業である Dbux を作成しました。これは現在、いくつかの制限付きで VSCode アドオンとしてのみ機能します。ただし、動的実行分析ツール、コード注釈、および本格的な動的呼び出しグラフ視覚化ツールを備えた全知のデバッガーであり、プログラムの理解とデバッグで開発者を支援することを目的としています。

リンク:

于 2020-09-28T20:14:06.807 に答える