【问题标题】:Unrolling an ...args array in a function call在函数调用中展开 ...args 数组
【发布时间】:2011-05-24 20:46:04
【问题描述】:

我正在对 JavaScript 方法进行大量 ExternalInterface 调用,并为此提供了一个辅助函数:

protected function JSCall( methodName:String, ...args ):void
{
  try
  {
    ExternalInterface.call( methodName, args );
  }
  … etc …
}

然而,这意味着 JavaScript 方法只会传递一个参数 - 参数数组 - 这意味着我必须更改 JavaScript 以适应这一点,例如而不是:

function example(argument1, argument2)
{

}

我最终得到:

function example(args)
{
  var argument1 = args[0];
  var argument2 = args[1];
}

我想做的是展开传递给JSCall 方法的参数数组,以便每个参数单独传递给ExternalInterface 调用,这样:

JSCall('example', ['one', 'two'])

像这样工作:

ExternalInterface.call('example', 'one', 'two')

【问题讨论】:

    标签: javascript flash actionscript-3 externalinterface


    【解决方案1】:

    要从 flash 中调用带有多个参数的 javascript 函数,您所要做的就是:

    ExternalInterface.call.apply(null, [functionName, arg1, arg2, ..., argn]);
    

    如果您从另一个函数的参数变量列表中获取参数,那么您可以使用:

    function JSCall(methodName:String, ...args):void
    {
        if (ExternalInterface.available){
            args.unshift(methodName);
            ExternalInterface.call.apply(null, args);
        }
    
        //btw, you can do the same with trace(), or any other function
        args.unshift('Calling javascript function');
        trace.apply(null, args);
    }
    

    你会打电话的其他地方:

    JSCall('console.log', 'Testing', 123, true, {foo:'bar'});
    

    ...它会在您的 firebug/webkit 控制台上打印类似 Testing 123 true Object 的内容。

    这已经过测试并且可以肯定地工作,因为我在一个真实的项目中使用它。

    【讨论】:

      【解决方案2】:

      在 JavaScript 中,Function.call.apply(foo, [that, test, bla]) 的工作方式类似于 foo.call(that, test, bla),但由于 ExternalInterface.call 不等于 Function.prototype.call,我们需要在这里使用不同的方法。

      // Let's fake ExternalInterface
      var funcs = {
          example: function(arg1, arg2) {
              console.log(arg1, arg2);
          }
      };
      
      var ExternalInterface = {};
      ExternalInterface.call = function() {
          var f = funcs[arguments[0]];
          f.call.apply(f, arguments);
      }
      
      
      // This does crazy stuff.
      function JSCall(func, args) {
          args.unshift(func);
          ExternalInterface.call.apply(ExternalInterface, args);
      }
      
      // These do the same now
      ExternalInterface.call('example', 'one', 'two'); // one two
      JSCall('example', ['one', 'two']); // one two
      

      注意:我没有在 ActionScript 中对此进行测试。

      【讨论】:

        【解决方案3】:

        嘿,Cameron,您尝试过使用 Function.apply() 吗?试试这个:

        ExternalInterface.call.apply( methodName, args );
        

        这太疯狂了,它可能会奏效!

        【讨论】:

        • 这确实有效,很巧妙的hack,我自己已经用过几次了,看起来很奇怪,90%的人第一次看到它时不明白,但是嘿太棒了!
        • 您好 Mims/Ivo,不幸的是,虽然这不会导致任何编译/运行时 Flash 错误,但在尝试执行 EI 调用时会引发 JavaScript 错误。 @Ivo - 你有使用这种技术的真实例子吗?
        • 通过查看 apply() 的 API 文档,我可以看到以下内容是如何工作的:ExternalInterface.call.apply(null, [methodname, args]) 但这与直接使用 ExternalInterface.call 相同,但没有帮助 ;)跨度>
        • 我想知道这是否可行:'ExternalInterface.call(method.apply, args);'
        • 另外,我并没有不尊重的意思,也许你应该问问自己,以这种方式接近它是否为自己省去了任何麻烦。如果您只是为了避免添加 try catch 语句而这样做,则可以将其内联。如果有很多代码,你可以调用类似 prepForJSCall() 然后调用 ExternalInterface.call()。
        猜你喜欢
        • 2012-06-13
        • 1970-01-01
        • 1970-01-01
        • 2014-10-24
        • 2015-02-21
        • 2020-11-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多