【问题标题】:Actionscript 3 introspection -- function namesActionscript 3 内省——函数名
【发布时间】:2009-07-30 18:24:55
【问题描述】:

我正在尝试遍历对象的每个成员。对于每个成员,我检查它是否是一个函数。如果它是一个函数,我想获取它的名称并根据函数的名称执行一些逻辑。我不知道这是否可能。是吗?有什么建议吗?

示例:

var mems: Object = getMemberNames(obj, true);

for each(mem: Object in members) {
    if(!(mem is Function))
        continue;

    var func: Function = Function(mem);

    //I want something like this:
    if(func.getName().startsWith("xxxx")) {
        func.call(...);
    }

}

我很难在这方面找到很多东西。感谢您的帮助。

【问题讨论】:

    标签: apache-flex actionscript-3 function introspection


    【解决方案1】:

    您的伪代码已接近您想要的功能。但是,您可以使用简单的 for..in 循环遍历成员,并使用括号获取成员的值,而不是使用可以获取私有方法的 getMemberNames。例如:

    public function callxxxxMethods(o:Object):void
    {
      for(var name:String in o)
      {
        if(!(o[name] is Function))
          continue;
        if(name.startsWith("xxxx"))
        {
          o[name].call(...);
        }
      }
    }
    

    【讨论】:

    • 您还应该避免转换您正在检查的对象,因为转换非常昂贵,使用像'is'或'as'之类的东西 - 就像这个例子一样,会好得多。
    • 如果我错了,请纠正我,但我认为你不能转换为 Function。
    • @Tyler Egeto:当然可以,但我相信你不能立即调用它,就像这样:Function(o[name])(),你必须存储它:var foo:Function = 函数(o[名称]); foo();
    【解决方案2】:

    Dan Monego 的答案是钱,但只适用于动态成员。对于任何固定实例(或静态)成员,您必须使用 flash.utils.describeType:

    var description:XML = describeType(obj);
    
    /* By using E4X, we can use a sort of lamdba like statement to find the members
     * that match our criteria. In this case, we make sure the name starts with "xxx".
     */
    var methodNames:XMLList = description..method.(@name.substr(0, 3) == "xxx");
    
    for each (var method:XML in methodNames)
    {
        var callback:Function = obj[method.@name];
        callback(); // For calling with an unknown set of parameters, use callback.apply
    }
    

    如果您同时拥有动态成员和固定成员,请将此与 Dan 的答案结合使用。

    【讨论】:

      【解决方案3】:

      我做了一些工作并将这两种方法结合起来。请注意,它仅适用于公开可见的成员 - 在所有其他情况下返回 null。

          /**
           * Returns the name of a function. The function must be <b>publicly</b> visible,
           * otherwise nothing will be found and <code>null</code> returned.</br>Namespaces like
           * <code>internal</code>, <code>protected</code>, <code>private</code>, etc. cannot
           * be accessed by this method.
           * 
           * @param f The function you want to get the name of.
           * 
           * @return  The name of the function or <code>null</code> if no match was found.</br>
           *          In that case it is likely that the function is declared 
           *          in the <code>private</code> namespace.
           **/
          public static function getFunctionName(f:Function):String
          {
              // get the object that contains the function (this of f)
              var t:Object = getSavedThis(f); 
      
              // get all methods contained
              var methods:XMLList = describeType(t)..method.@name;
      
              for each (var m:String in methods)
              {
                  // return the method name if the thisObject of f (t) 
                  // has a property by that name 
                  // that is not null (null = doesn't exist) and 
                  // is strictly equal to the function we search the name of
                  if (t.hasOwnProperty(m) && t[m] != null && t[m] === f) return m;            
              }
              // if we arrive here, we haven't found anything... 
              // maybe the function is declared in the private namespace?
              return null;                                        
          }
      

      问候,

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-10-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-12-03
        • 2017-08-18
        相关资源
        最近更新 更多