唯一ID或对象签名

时间:2012-12-18 21:39:50

标签: javascript

我正在开发一个Logging系统,我期待着实现一次 log 方法。

我坚持的是,如何检索唯一标识符和/或对象签名,以用作哈希键?

我的想法是:

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>]。没有ids,没有任何东西。

我还尝试了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.

1 个答案:

答案 0 :(得分:3)

您可以使用JSON.stringify获取任意值的“签名”。当然,这不会保存对象类型,也不适用于DateFunction个实例;它也不区分具有相同值的不同对象。如果你想要,你需要存储一个明确的引用(当然阻碍垃圾收集器释放它们):

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

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