我正在开发一个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.
答案 0 :(得分: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
} …
请注意,此解决方案不适用于原始值,甚至对null
和undefined
都失败 - 您可能需要混合使用这两种方法。