如何在Rhino中创建一个"真正的"JavaScript数组

n3r*_*3rd 7 javascript arrays rhino

好的,我有点难过.我可能错过了一些明显的东西,但显然我只是看不到森林的树木:

我试图调用一个JavaScript函数,期望它的参数是一个数组,即它检查if (arg instanceof Array)...不幸的是,我(或Rhino)似乎无法创建这样的数组:

  Context cx = Context.enter();
  Scriptable scope = cx.initStandardObjects();
  String src = "function f(a) { return a instanceof Array; };";

  cx.evaluateString(scope, src, "<src>", 0, null);

  Function f = (Function) scope.get("f", scope);
  Object[] fArgs = new Object[]{ new NativeArray(0) };
  Object result = f.call(cx, scope, scope, fArgs);

  System.out.println(Context.toString(result));

  Context.exit();
Run Code Online (Sandbox Code Playgroud)

唉,result是的false.

我在这里错过了什么?

编辑:
再多一点信息:两者[] instanceof Array并按照人们的预期new Array() instanceof Array返回true.如果我向数组添加元素,它们会在JavaScript代码中显示正确的索引(数字,从零开始):

  NativeArray a = new NativeArray(new Object[]{ 42, "foo" });
Run Code Online (Sandbox Code Playgroud)

使用此JavaScript函数输出时:

  function f(a) {
      var result = [];
      result.push(typeof a);
      for (var i in a) {
          result.push(i + ' => ' + a[i]);
      }
      return result.join('\\n');
  }
Run Code Online (Sandbox Code Playgroud)

结果是:

  object
  0 => 42
  1 => foo
Run Code Online (Sandbox Code Playgroud)

所以它有效.除了我想要一个'真正的'数组:)

T.J*_*der 8

差点忘了:Object.prototype.toString.call(a)退货[object Array]

好的,这是至关重要的信息.这告诉我们数组实际上是一个数组,只是它被一个Array构造函数初始化,该构造函数的范围与函数测试的范围不同,就像你在一个窗口中测试一个数组而不是另一个窗口的Array构造函数一样.基于浏览器的应用程序.例如,存在范围问题.

尝试更换

Object[] fArgs = new Object[]{ new NativeArray(0) };
Run Code Online (Sandbox Code Playgroud)

Object[] fArgs = new Object[]{ cx.newArray(scope, 0) };
Run Code Online (Sandbox Code Playgroud)

...以确保使用正确的Array构造函数.因为你直接去了NativeArray构造函数,你绕过确保其范围是正确的,所以数组对象constructor一个 Array构造函数,但不是相同的 Array构造函数作为全局对象的功能上看到的一个.