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

时间:2016-11-26 02:49:42

标签: javascript actionscript-3 flash

我正在编写调试工具,我想说清楚我在哪里。我的理想输出会将类名和函数名写入控制台,如下所示:

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中工作。

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

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);
}

1 个答案:

答案 0 :(得分:0)

如果我使用error.getStackTrace(),我可以使用以下方法获取当前类,方法,文档,文档文件路径和行号的名称。发布版本中不提供文档,文件路径和行号。这仅适用于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添加到您的类中,您可以调用以下任何方法:

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

getCurrentLocation()返回一个包含类名,方法名的对象,如果在内容调试器中运行,则返回文档,文档路径和行号。