2

私はロギング システムに取り組んでおり、ログ ワンスメソッドを実装することを楽しみにしています。

私が立ち往生しているのは、一意の識別子やオブジェクトの署名を取得して、ハッシュキーとして使用するにはどうすればよいですか?

私の考えは:

var Log = {
    messages : {},
    once : function(message)
    {
        // get unique id and/or passed objects signature, use it as a key
        var key = unique( message );

        if ( !Log.messages.hasOwnProperty(key) )
        {
            Log.messages[key] = message;
        }
    }
};

を試してみましたが、単純に基本的なオブジェクトとそれ以外のオブジェクトに対して.toString()返されました。IDなし、何もありません。[object Object][object <type>]

私もそのtoSource()機能を試してみましたが、Chrome では基本的なオブジェクトを操作したくありませんでした。

ただし、必要なのは、これがあらゆるタイプのオブジェクトで機能することです。文字列であれ、整数であれ、関数であれ、その署名/IDを取得する必要があります。

たぶん、そのような機能の実装はすでにどこかにありますか?

アップデート

これは、ループでログを記録することを意図していますが、コンソールの汚染を防ぐために、繰り返しごとにログを記録するのではなく、1 回だけログを記録します。

私の特定のループは実際にはゲーム ループであり、いくつかの情報をデバッグしようとしています。

お気に入り:

for (var i = 0; i < 100; i++)
{
    console.log('message');
}
// this would log 100 entries

どこ:

for (var i = 0; i < 100; i++)
{
    Log.once('message');
}
// would execute behind the scenes console.log() only once.
4

1 に答える 1

3

JSON.stringify任意の値の「署名」を取得するために使用できます。もちろん、これはオブジェクト タイプを保存せず、DateまたはFunctionインスタンスに対しては機能しません。また、同じ値を持つ異なるオブジェクトを区別しません。それが必要な場合は、それらへの明示的な参照を保存する必要があります (もちろん、ガベージ コレクターがそれらを解放するのを妨げます):

var loggedVals = [];
console.once = function() {
    var args = [].slice.call(arguments).filter(function(arg) {
        return (loggedVals.lastIndexOf(arg)==-1) && loggedVals.push(arg);
    });
    if (args.length)
        console.log.apply(console, args);
});

それらへの参照を保存したくない場合は、隠しプロパティを追加して「ログ済み」としてタグ付けする必要があります (UID ジェネレーターが行うのと同じように)。

… function(arg) {
        return !arg.__hasbeenlogged__ && 
          Object.defineProperty(arg, "__hasbeenlogged__", {value: true});
          // configurable, enumarable and writable are implicitly false
    } …

この解決策は、プリミティブ値に対しては機能せず、and に対しても失敗することに注意してください。2 つのアプローチを組み合わせる必要がある場合がありますnullundefined

于 2012-12-18T22:02:17.407 に答える