如果我给你一个函数的引用,你能得到函数的名称吗?

If I give you a reference to the function can you get the name of the function?

我正在编写调试工具,我想说清楚我的位置。我理想的输出是将 class 名称和函数名称写入控制台,如下所示:

Vehicle.addWheels()
  Wheels were added by the user

在代码中它会是这样一个函数:

trace(addWheels, "Wheels were added by the user");

我正在考虑编写一个自定义函数来获取像这样的详细信息(伪代码):

public static myTrace(function:Function, message:String):void {
   var className:String = function.parent;
   var functionName:String = getQualifiedName(function.prototype);
   trace(className + "." + functionName + ": " + message);
}

这是一个 AS3 示例,但 AS3 基于 JavaScript,因此如果它适用于 Javascript,它可能适用于 ActionScript。

如果这不起作用,我可以使用第三个参数轻松传入 class 引用,但仍然需要知道如何获取函数名称。

public static myTrace(object:Object, function:Function, message:String):void {
   var className:String = getQualifiedName(object);
   var functionName:String = getQualifiedName(function.prototype);
   trace(className + "." + functionName + ": " + message);
}

如果我使用error.getStackTrace()我可以使用下面的方法获取当前class的名称、方法、文档、文档文件路径和行号。文档、文件路径和行号在发布版本中不可用。这仅适用于 FP 11.4 之后的发布版本。

protected function drawLayer_clickHandler(event:MouseEvent):void
{
    var stack:Array = getStackArray();
    var object:Object = getCurrentLocation();
    var className:Object = getCurrentClassName();
    var functionName:Object = getCurrentFunctionName();

}

protected static function getStackTrace(removeLines:Boolean = true):String {
    var error:Error = new Error();
    var value:String;
    var stackTrace:Array;

    if ("getStackTrace" in error) {
        value = error.getStackTrace();
        value = value.replace(/\t/g, "");
        if (removeLines) {
            value = value.replace(/\[.*\]/g, "");
            value = value.replace(/.*?::/g, "");
        }
        stackTrace = value.split("\n");
        stackTrace.shift();
        stackTrace.shift();
        return stackTrace.join("\n");
    }

    return null;
}

protected static function getCurrentClassName():String {
    var object:Object = getCurrentLocation(2);
    var className:String = object ? object.className: null;

    return className;
}

protected static function getCurrentFunctionName():String {
    var object:Object = getCurrentLocation(2);
    var functionName:String = object ? object.functionName: null;

    return functionName;
}

public static function getCurrentLocation(offset:int = 1):Object {
    var stack:Array = getStackArray(1, offset);
    var object:Object = stack && stack.length ? stack[0] : null;

    return object;
}

protected static function getStackArray(results:int = 0, offset:int = 0):Array {
    var error:Error = new Error();
    var value:String;
    var stackTrace:Array;
    var object:Object;
    var className:String;
    var functionName:String;
    var fileLocation:String;
    var lineNumber:String;
    var message:String;
    var components:Object;
    var matchPattern:RegExp;
    var path:String;
    var stack:Array;
    var locations:Array;

    matchPattern = /^at\s(.+?)\(\)\[(.*?):(.*)]/;

    if ("getStackTrace" in error) {
        value = error.getStackTrace();
        value = value.replace(/\t/g, "");
        //value = value.replace(/\[.*\]/g, "");
        //value = value.replace(/.*?::/g, "");
        stackTrace = value.split("\n");
        stackTrace.shift();// removes Error at
        stackTrace.shift(); // removes this function

        for (; offset >0 && stackTrace.length; offset--) {
            stackTrace.shift();
        }

        stack = [];

        for (var i:int = 0; i < stackTrace.length; i++) {
            object = {};
            message = stackTrace[i];
            components = message.match(matchPattern);

            // matches 
            // "at TransformTests/drawLayer_clickHandler()[/Documents/Project/src/TransformTests.mxml:244]"
            if (components) {
                locations = components[1].split(/[\|\/]/);

                // class and method
                if (locations.length>1) {
                    object.className = locations[0];
                    object.functionName = locations[1];
                }
                // global method - has no class
                else if (locations.length) {
                    object.functionName = locations[0];
                }

                path = components[2];

                object.location = path;
                object.document = path ? path.split(/[\|\/]/).pop() : null;
                object.lineNumber = components[3];
                stack.push(object);
            }
            else {
                // matches "at Transform/drawLayer_clickHandler()" or "at drawLayer_clickHandler()"
                components = message.match(/^at\s(.*)\(\)/);

                // runtime has no file path or line number
                if (components) {
                    path = components[1];
                    locations = path.split(/[\|\/]/);

                    // class and method
                    if (locations.length>1) {
                        object.className = locations[0];
                        object.functionName = locations[1];
                    }
                    // global method - no class
                    else if (locations.length) {
                        object.functionName = locations[0];
                    }

                    stack.push(object);
                }

            }

            if (results==i+1) {
                break;
            }
        }

        return stack;
    }

    return null;
}

我在 github 库中添加了一些全局函数来获取此信息。将 swc 添加到您的 class,您可以调用以下任何方法:

log();
log("message");
logTarget(object, "message");
getCurrentClassName();
getCurrentFunctionName();
getCurrentLocation();
getStackArray();

getCurrentLocation() returns 包含 class 名称、方法名称的对象,如果 运行 在内容调试器中 returns 文档、文档路径和电话号码。