6

我有一个函数,它可以接受带有休息运算符的可变数量的参数。

我想创建一个对象,将使用 rest 运算符收集的参数直接传递给构造函数,而不创建对象并调用初始化函数,并且不传递整个数组,但参数啊,我使用 apply() 函数。

可能吗 ?使用 apply 不起作用。

public function myFunc(...arg) {

     // something link "new MyClass.apply(args)"
     return new MyClass();

}
4

4 回答 4

14

抱歉不行。没有办法使构造函数的应用工作。通常所做的是根据参数的数量准备一些调用:

public function myFunc(...arg):Myclass {
  switch (arg.length) {
    case 0:return new MyClass();
    case 1:return new MyClass(arg[0]);
    case 2:return new MyClass(arg[0], arg[1]);

    //... etc

    case n:return new MyClass(arg[0], arg[1],..,arg[n]);
    default: throw new Error("too much arguments in myFunc");
  }
}
于 2010-10-06T18:14:33.417 回答
2

Well this led me to an interesting long research!

I found this neat SWC file filled with utils for mimicking the AS2 eval(): http://www.riaone.com/products/deval/index.html

And here's a proof of concept that what you're looking for might actually work:

package tests {
    import flash.display.BitmapData;
    import flash.display.Sprite;
    import flash.utils.getQualifiedClassName;
    import r1.deval.D;

    public class RandomTests extends Sprite{

        public function RandomTests() {
            super();

            var test:BitmapData =   create(BitmapData, 100, 100, true, 0x00000000);
            trace(test);
        }


        public function create( pClass:Class, ... pArgs ):* {
            D.importClass(pClass);
            var fullQName:String =  getQualifiedClassName(pClass);
            var qNameSplit:Array =  fullQName.split("::");
            var className:String =  qNameSplit[1];
            fullQName =             qNameSplit.join(".");

            var statements:String =
            "import $0;\n" +
            "return new $1($2);";


            var args:Array =        [];
            for (var a:int = 0, aLen:int = pArgs.length; a < aLen; a++) {
                switch(pArgs[a].constructor) {
                    case String:
                        args[a] =   "\"" + pArgs[a] + "\"";
                        break;
                    default:
                        args[a] =   pArgs[a];
                        break;
                        //throw new Error("Unhandled type, please add it: " + pArgs[a].constructor);
                }
            }

            return D.eval(XString.gsub(statements,[fullQName, className, args.join(",")]));
        }
    }

}

Sorry for the bits of dependencies (Like my XString class for easy sub-replacements) but it does work in theory. The only issue would be passing object references as argument entries. But then again... the r1.deval.D class might be able to take it... hmm.

Anyways, thought maybe this would be worth sharing.

于 2010-10-14T19:15:30.760 回答
0

还有这个

public function myFunc(args:Object) {

   //then access various argumens
   return new MyClass(args.name, args.id, args.active)

}

并通过调用它myFunc({id:33,name:'jo')

然后您可以传递该对象,或者这与您要查找的内容相去甚远?

于 2010-10-06T19:05:10.260 回答
0

我也在寻找答案,但太难过看到答案是否定的......

这是我目前(不太好)做这种事情的方法,希望你们中的一些人感兴趣:

// Foo.as
public class Foo {
    // construct
    public function Foo(... args):void {
        create.apply(this, args);
    }

    // this function do as a really construct function, tricky stuff
    function create(id:uint, name:String) {
        trace(id, name);
    }
}

// Bar.as
// for create this kind of class, just new it as usual
...
var foo:Foo = new Foo(123, "abc");
...
于 2011-11-03T04:29:34.433 回答