在 chrome 开发工具中记录匿名函数
Logging anonymous function in the chrome dev tools
我有一些这样的代码:
obj.addEventListener('event', function(eventType) {
});
当我在 chrome web deveoper Profiler 中调试它时,我总是将其视为匿名函数,但我更愿意将其视为 eventType 的内容。
是否可以以某种方式重命名或包装它,最好以一种有效的方式,而不需要为每个 eventType 单独的函数?
或者是否可以像在时间轴中那样为探查器添加时间戳,以便我可以区分不同的事件类型?
谢谢!
您可以使用命名函数表达式为您的函数指定一个名称,该名称将显示在探查器中,而不是“(匿名函数)”:
obj.addEventListener('event', function myHandler(eventType) {
});
在上述情况下,处理程序将在分析器中显示为 "myHandler"。
我认为您需要澄清 "rename or wrap this somehow, preferable in an efficent way, without the need of a separate function for each eventType" 的意思。从您的示例来看,您似乎在为每种事件类型使用单独的函数。
您希望函数名称取决于其参数,"without the need of a separate function for each eventType"?
我觉得那真的是不可能的。
显然,一个函数保留了创建时分配给它的名称。
尝试以下操作:
var aaa = function()
{
debugger;
};
var bbb = aaa;
delete aaa;
(function(){ var ccc = bbb; ccc(); })();
当我 运行 上面的代码时,我在调试器中看到 "aaa",我怀疑它在开发工具的其他部分会有所不同。
我虽然也许有人可以篡改 arguments.callee
:
var aaa = function()
{
console.log(arguments.callee.name);
arguments.callee.name = 'bbb';
console.log(arguments.callee.name);
debugger;
};
(function()
{
var ccc = aaa;
console.log(ccc.name);
ccc.name = 'ccc';
console.log(ccc.name);
ccc();
})();
但这四次在控制台上什么也没有记录,这与 arguments.callee.prototype.constructor.name
完全相同。
仅记录 arguments.callee.prototype
记录 aaa {}
,这表明该名称以某种方式在内部绑定。
所以如果不创建额外的功能,这几乎是不可能的。
您可以使用 one 名称作为函数名称,如 .
中所建议
除此之外,您别无选择,只能在运行时间创建一些函数。
这不会使它们在探查器中显示为不同的函数,但是,您可能应该有一个全局对象,您可以在该对象上分配创建的函数,以便您可以重用它们。
我建议采用以下设置:
使实际的处理函数成为全局函数,例如:
function actualEventHandler(eventType) { /* ... */ }
有一个全局对象来将您即时创建的函数存储到:
var handlerFunctions = {};
然后在您指定的事件处理函数中,检查当前事件类型的函数是否已经存在,否则创建一个名称基于该类型的函数:
obj.addEventListener('event', function(eventType)
{
if(handlerFunctions[eventType] === undefined)
{
var ev = {};
ev[eventType] = function(evType)
{
actualEventHandler(evType);
}
handlerFunctions[eventType] = ev[eventType];
}
handlerFunctions[eventType](eventType);
});
由于您无法使用字符串名称创建变量,因此我在这里使用临时对象 ev
,因此函数名称将为 ev.<whatever>
。如果您根本不需要任何前缀,则必须使用 eval()
.
编辑: 似乎在 Chrome 的较新版本中,使用临时对象的技巧不再有效,因为 Chrome 现在只显示 ev.(anonymous function)
。你仍然可以用 eval
来做,只要 eventType
是一个有效的函数名:
obj.addEventListener('event', function(eventType)
{
if(handlerFunctions[eventType] === undefined)
{
var fn = null;
eval('fn = function ev_' + eventType + '(evType){ actualEventHandler(evType); };');
handlerFunctions[eventType] = fn;
}
handlerFunctions[eventType](eventType);
});
然后您的函数将显示在以 ev_
为前缀的堆栈跟踪中。
我不知道这在探查器中的反映有多好,所有这些函数仍然会有一个匿名函数(传递给 addEventListener
的函数 - 你可以给它起个名字,但我不确定这是否真的有帮助)并在内部调用 actualEventHandler
,但它实际上应该显示所有事件类型的不同功能。
我有一些这样的代码:
obj.addEventListener('event', function(eventType) {
});
当我在 chrome web deveoper Profiler 中调试它时,我总是将其视为匿名函数,但我更愿意将其视为 eventType 的内容。
是否可以以某种方式重命名或包装它,最好以一种有效的方式,而不需要为每个 eventType 单独的函数?
或者是否可以像在时间轴中那样为探查器添加时间戳,以便我可以区分不同的事件类型?
谢谢!
您可以使用命名函数表达式为您的函数指定一个名称,该名称将显示在探查器中,而不是“(匿名函数)”:
obj.addEventListener('event', function myHandler(eventType) {
});
在上述情况下,处理程序将在分析器中显示为 "myHandler"。
我认为您需要澄清 "rename or wrap this somehow, preferable in an efficent way, without the need of a separate function for each eventType" 的意思。从您的示例来看,您似乎在为每种事件类型使用单独的函数。
您希望函数名称取决于其参数,"without the need of a separate function for each eventType"?
我觉得那真的是不可能的。
显然,一个函数保留了创建时分配给它的名称。
尝试以下操作:
var aaa = function()
{
debugger;
};
var bbb = aaa;
delete aaa;
(function(){ var ccc = bbb; ccc(); })();
当我 运行 上面的代码时,我在调试器中看到 "aaa",我怀疑它在开发工具的其他部分会有所不同。
我虽然也许有人可以篡改 arguments.callee
:
var aaa = function()
{
console.log(arguments.callee.name);
arguments.callee.name = 'bbb';
console.log(arguments.callee.name);
debugger;
};
(function()
{
var ccc = aaa;
console.log(ccc.name);
ccc.name = 'ccc';
console.log(ccc.name);
ccc();
})();
但这四次在控制台上什么也没有记录,这与 arguments.callee.prototype.constructor.name
完全相同。
仅记录 arguments.callee.prototype
记录 aaa {}
,这表明该名称以某种方式在内部绑定。
所以如果不创建额外的功能,这几乎是不可能的。
您可以使用 one 名称作为函数名称,如
除此之外,您别无选择,只能在运行时间创建一些函数。
这不会使它们在探查器中显示为不同的函数,但是,您可能应该有一个全局对象,您可以在该对象上分配创建的函数,以便您可以重用它们。
我建议采用以下设置:
使实际的处理函数成为全局函数,例如:
function actualEventHandler(eventType) { /* ... */ }
有一个全局对象来将您即时创建的函数存储到:
var handlerFunctions = {};
然后在您指定的事件处理函数中,检查当前事件类型的函数是否已经存在,否则创建一个名称基于该类型的函数:
obj.addEventListener('event', function(eventType)
{
if(handlerFunctions[eventType] === undefined)
{
var ev = {};
ev[eventType] = function(evType)
{
actualEventHandler(evType);
}
handlerFunctions[eventType] = ev[eventType];
}
handlerFunctions[eventType](eventType);
});
由于您无法使用字符串名称创建变量,因此我在这里使用临时对象 ev
,因此函数名称将为 ev.<whatever>
。如果您根本不需要任何前缀,则必须使用 eval()
.
编辑: 似乎在 Chrome 的较新版本中,使用临时对象的技巧不再有效,因为 Chrome 现在只显示 ev.(anonymous function)
。你仍然可以用 eval
来做,只要 eventType
是一个有效的函数名:
obj.addEventListener('event', function(eventType)
{
if(handlerFunctions[eventType] === undefined)
{
var fn = null;
eval('fn = function ev_' + eventType + '(evType){ actualEventHandler(evType); };');
handlerFunctions[eventType] = fn;
}
handlerFunctions[eventType](eventType);
});
然后您的函数将显示在以 ev_
为前缀的堆栈跟踪中。
我不知道这在探查器中的反映有多好,所有这些函数仍然会有一个匿名函数(传递给 addEventListener
的函数 - 你可以给它起个名字,但我不确定这是否真的有帮助)并在内部调用 actualEventHandler
,但它实际上应该显示所有事件类型的不同功能。