简体   繁体   English

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

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

I'm writing debugging tools and I want to make it clear where I'm at. 我正在编写调试工具,我想清楚地知道我在哪里。 My ideal output would write the class name and function name to the console like so: 我的理想输出会将类名和函数名写入控制台,如下所示:

Vehicle.addWheels()
  Wheels were added by the user

and in code it would be a function like: 在代码中它将是一个函数,如:

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

I'm thinking of writing a custom function that gets the details like so (pseudo code): 我正在考虑编写一个自定义函数来获取类似的细节(伪代码):

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

This is an AS3 example but AS3 is based on JavaScript so if it works in Javascript it may work in ActionScript. 这是一个AS3示例,但AS3基于JavaScript,因此如果它在Javascript中工作,它可以在ActionScript中工作。

If that doesn't work I can pass in the class reference easily using a third parameter but still need to know how to get the name of the function. 如果这不起作用,我可以使用第三个参数轻松传入类引用,但仍需要知道如何获取函数的名称。

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

If I use error.getStackTrace() I can use the following methods to get the name of the current class, method, document, document file path and line number. 如果我使用error.getStackTrace(),我可以使用以下方法获取当前类,方法,文档,文档文件路径和行号的名称。 The document, file path and line number aren't available in release builds. 发布版本中不提供文档,文件路径和行号。 This only works in release builds after FP 11.4. 这仅适用于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;
}

I added a few global functions for getting this information in the github library. 我添加了一些全局函数来获取github库中的这些信息。 Add the swc to your class and you can call any of the following methods: 将swc添加到您的类中,您可以调用以下任何方法:

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

The getCurrentLocation() returns an object that contains the class name, method name and if running in the content debugger returns the document, document path and line number. getCurrentLocation()返回一个包含类名,方法名的对象,如果在内容调试器中运行,则返回文档,文档路径和行号。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如果仅知道函数名称,如何获取对数组中函数的引用? - How to get reference to function in array if you know only the name of function? 在Javascript中,如果有一个函数,可以按名称获取参数吗? - In Javascript, if you have a function can you get the arguments by name? Javascript function - 你能给arguments这样的吗? - Javascript function - Can you give arguments like this? 你能得到调用函数的属性名吗? - Can you get the property name through which a function was called? 你能在javascript中引用一个解构的function参数吗? - Can you reference a destructured function parameter in javascript? 我该如何制作一个带有参数的函数,并且在执行该函数时,它会提示您提供给函数的任何内容? - How can I make a function that takes in a parameter and when executed, it alerts whatever you give the function? 为什么调试器会给您“未定义的不是函数”,而不仅仅是告诉您不是函数的属性/变量的名称? - Why does debuggers give you “undefined is not a function” instead of just telling you the name of the property/variable that is not a function? 您如何命名一个函数,以便您可以对其进行自省? - How do you name a function so that you can introspect it? 您可以引用ngOnInit中创建的函数吗? - Can you reference a function that's created within ngOnInit? JavaScript / JQuery-您可以将引用传递给函数然后执行它吗? - JavaScript/JQuery - can you pass a reference to a function and then execute it?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM