5

我是犀牛的新手。

目前,我通过 .NET 4 和 IKVM.NET 使用 Rhino 1.7R 框架。我使用 setWrapFractory() API 公开了几个实现 NativeJavaObject 的包装类。

public class InterceptNativeObject : NativeJavaObject
{
    public InterceptNativeObject()
    {

    }

    public override Object get(String name, Scriptable start)
    {
        Object res = base.get(name, start);
        if (res is NativeJavaMethod)
        {
            NativeJavaMethod method = (NativeJavaMethod)res;
            return new RhinoMethodWrapFunction(method);
        }
        if (res == org.mozilla.javascript.UniqueTag.NOT_FOUND &&
            base.javaObject is IPropertBox && base.javaObject != null)
        {
            object ret = ((IPropertBox)base.javaObject)._x__GetPropertyValue(name);

            return Utils.ConvertCLRValueToJavaValue(ret);
        }
        return res;
     }

     .....
}

现在,我可以根据需要访问所有 .NET 方法和属性。

我当前的问题是支持“for...in”我的 NativeJavaObject 类。当我评估

     'for(var prop in myClass){printf(prop);};' ,

它返回“no 'in' call for non-object”错误。

似乎“get”试图搜索“ _iterator _ ”的对象,但在 get() 函数中导致“未找到”。因此,它以异常结束。到目前为止,我尝试过

  • 添加了 java.util.iterator
  • 返回 this.getIds().GetEnumrator();

没有作品。

如何允许对 Wrapped NativeJavaObject 进行属性枚举访问?Rhino启用“for...in”的“ _iterator_ ”预期返回值是多少?

提前致谢!

4

1 回答 1

2

__iterator__Mozilla 特定语言扩展的一部分。该链接解释了该__iterator__方法返回一个对象,该对象带有一个在迭代器耗尽时next抛出的方法。StopIteration

您必须选择加入迭代器和生成器:

Context.setLanguageVersion()要启用 JavaScript 1.7 支持,您必须使用API 调用将版本设置为 170 。如果您使用的是 Rhino shell,您可以-version 170在命令行中指定或在 shell 执行的代码中调用 version(170)。

您可以在 rhino 中编写 JS,它将包装 Java 迭代器以将其呈现为 JS 迭代器:

function javaIteratorToJsIterator(javaIterator) {
  return {
    next: function () {
      if (!javaIterator.hasNext()) { throw StopIteration; }
      return javaIterator.next();
    }
  };
}

或者,您可以使用 Mozilla 样式生成器,但我认为您需要创建带有启用它们的选项的 Rhino 解释器。

虽然自定义迭代器是一个有用的工具,但它们的创建需要仔细编程,因为需要显式维护它们的内部状态。生成器提供了一个强大的替代方案:它们允许您通过编写一个可以维护自己状态的函数来定义迭代算法。

生成器是一种特殊类型的函数,可用作迭代器的工厂。如果一个函数包含一个或多个 yield 表达式,它就会成为一个生成器。

于 2012-12-13T08:14:16.973 回答