【 以下文字转载自 Google 讨论区 】
发信人: modico (modico), 信区: Google
标 题: gmail client code review,part 6
发信站: 水木社区 (Fri Oct 20 13:06:19 2006), 站内
关于获取一个函数的名称.
JavaScript Function 对象并没有一个 name 属性,它可以跟任何变量名关联,跟一个或多个名称关联, function A 基本上就是 var A = function(), 你可以推测 A 和 B是否指向同一个函数,但是很难从一个函数反推它跟哪个或哪些变量关联。
当有 function A(){}; B=A; A=1; 时,你从B指向的函数里推测是A变量,而其实A已经不再指向函数。那么要完成这个不能完成的任务,只有用道德法则去约束开发员,让他们不要那么淘气,定义函数时最好就是写成 function A(){} 这样函数的 toString() 方法可以返回函数源码,然后分析字符串,解析出 function 后面跟的那个函数名。
但对于类似成员方法的定义就不可能用 function A() 这种简单的方法了,微软扩展了ECMAScript 标准,可以用 function A.prototype.B() 这种定义,其它大部分浏览器都不支持,所以只能用 A.prototype.B = function(). 对于这种情况用上面的方法也就没有效果了。用一个笨方法,就是轮询所有变量,每个变量的每个prototype成员,就如google做的那样,它也只是轮询了一层,就是所有全局变量的prototype成员。它也不敢多做几层,这样又会引发无限循环的问题。
算了,勉强吧,对于这种勉强的任务,也只能勉强的实现了。
var g_funcnameRgx/*BC*/ = /function (\w+)/;
function getFunctionName/*Gr*/(func)
{
var b = g_funcnameRgx/*BC*/.exec(String(func));
return b ? b[1] : getMethodNameOfGlobalObject/*Gs*/(func);
}
function getMethodNameOfGlobalObject/*Gs*/(func)
{
for (var b in window) {
try {
if (g_uaNotIE_KHtml/*BP*/ && (b == "Packages" || b == "sun" || b == "netscape" || b == "java")) {
continue;
}
var c = window[b];
if (c) {
var d = c.prototype;
if (d) {
for (var e in d) {
if (d[e] == func) {
return b + "." + e;
}
}
}
}
}
catch (f) {}
}
return "";
}
--
FROM 218.249.84.*