我可以将 apply() 与构造函数一起使用来传递任意数量的参数吗

发布于 2024-09-26 12:44:00 字数 286 浏览 1 评论 0原文

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

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

是否可以 ?使用 apply 不起作用。

public function myFunc(...arg) {

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

}

I've got a function wich can accept a varible number of parameter with a rest operator.

I want create an object passing the argument collected with the rest operator directly to a constructor without create an object and call an initializing function and without passing the entire array but the parameters ah I do with apply() function.

Is it possible ? Using apply doesn't work.

public function myFunc(...arg) {

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

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

凉城已无爱 2024-10-03 12:44:00

不幸的是没有。没有办法让 apply 为构造函数工作。通常所做的是根据参数的数量准备多个调用:

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

Unfortunately no. There is no way to make apply work for constructor. What is done generally is to prepare a number of call based on the number of arguments :

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");
  }
}
仙气飘飘 2024-10-03 12:44:00

好吧,这让我进行了一项有趣的长期研究!

我发现这个简洁的 SWC 文件充满了用于模仿 AS2 eval() 的实用程序:
http://www.riaone.com/products/deval/index.html

这是一个概念证明,您正在寻找的内容可能实际上有效:

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(",")]));
        }
    }

}

抱歉,有些依赖关系(就像我的 XString 类,可以轻松进行子替换),但它在理论上确实有效。唯一的问题是将对象引用作为参数条目传递。但话又说回来... r1.deval.D 类也许能够接受它... 嗯。

不管怎样,我想也许这值得分享。

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.

浅浅淡淡 2024-10-03 12:44:00

好吧,还有这个

public function myFunc(args:Object) {

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

}

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

然后您可以传递该对象,或者这离您要寻找的东西太远了?

well there's also this

public function myFunc(args:Object) {

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

}

and call it through myFunc({id:33,name:'jo')

you could then pass the object, or is this too far from what you're looking for?

黎夕旧梦 2024-10-03 12:44:00

我也在寻找答案,但很遗憾看到答案是否定的......

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

// 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");
...

I'm searching for the answer too, but too sad to see the answer is no....

Here's my current (not so good) way to do this kind of stuff, hope some of you interest:

// 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");
...
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文