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()了,但它确实只是[object Object]为一个基本对象和[object <type>]其他任何东西返回。没有身份证,什么都没有。

我也尝试了该toSource()功能,但在 Chrome 中它不想使用基本对象。

不过,我需要的是让它适用于每种类型的对象。无论是字符串、整数还是函数,我都需要获取该签名/ID。

也许已经在某个地方实现了这样的功能?

更新

这意味着在循环中进行日志记录,但不是每次迭代都记录,而是只记录一次,以防止控制台污染。

我的特定循环实际上是一个游戏循环,我希望调试一些信息。

喜欢:

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来获取任意值的“签名”。当然这不会保存对象类型,也不适用于DateorFunction实例;它也不区分具有相同值的不同对象。如果需要,您需要存储对它们的显式引用(当然会阻碍垃圾收集器释放它们):

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
    } …

请注意,此解决方案不适用于原始值,甚至无法用于nulland undefined- 您可能需要混合使用这两种方法。

于 2012-12-18T22:02:17.407 回答