如何在Rhino中启用'for ... in'我的NativeJavaObject?

时间:2012-12-13 08:07:10

标签: javascript .net rhino ikvm

我是犀牛的新手。

目前,我正在通过.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'。

似乎'get'试图搜索' _ iterator _ '的对象,但是在get()函数中导致'not found'。所以,最终会有例外。   到目前为止,我试过了

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

没有作品。

如何允许我的Wrapped NativeJavaObject的属性枚举访问?    什么是Rhino预期的' _ 迭代器 _ '的返回值,以启用'for ... in'?

提前致谢!

1 个答案:

答案 0 :(得分:2)

__iterator__Mozilla specific language extension的一部分。该链接解释了__iterator__方法返回一个对象,其中next方法在迭代器耗尽时抛出StopIteration

你必须opt in到迭代器和生成器:

  

要启用JavaScript 1.7支持,您必须使用Context.setLanguageVersion() 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表达式,则该函数将成为生成器。