Hi Walter,
thanks for trying out Nashorn and for your feedback. Nashorn's Java interop is
different from Rhino's. The object models of Java and JavaScript are
sufficiently different that a lot of functionality isn't straightforward to
implement. We have chosen to err on the side of caution, and if we weren't
convinced that something is the right way to do, we'd rather not implementing
it than implement it in what we felt was the wrong way. We're open to community
discussion - few months ago we have changed the way JS arrays are exposed to
Java API after a discussion on this list.
That said, for…in over Java objects is not straightforward, as it'd require us
to decide which of the properties are enumerable, and which are not. E.g. would
we want every object to expose a property "class" since it has a getClass()
method? While we're at it, for a property getter method (let's stay with
getClass), should it expose both a "class" property and a "getClass" property
which returns a callable representation of the method? (Right now, this is
moot, as you can't call .apply and .call on Java methods, but we might change
that in the future). If applied to an Java List or Map, should it only return
indices/keys, or object methods and properties too?
When we feel that the gap in the object model are too large, we'd rather
provide an explicit API that people can use than implement implicit
non-specification behavior that's papers over this too large gap, and that's
not apparent from reading the source code.
Speaking of such explicit APIs, there's a solution. Nashorn exposes a
(non-ECMAScript standard) method Object.bindProperties() that allows you to get
properties from one object, bind them to that object, and expose them in
another object. E.g. if you want to iterate over methods and properties of an
ArrayList:
var x = {}
var y = new java.util.ArrayList();
Object.bindProperties(x, y)
for(var i in x) {
print(i);
}
will output:
getClass
wait
notifyAll
replaceAll
notify
remove
iterator
removeAll
stream
...
You can also selectively remove properties or otherwise edit the "x" object for
further use (something you couldn't do with ArrayList proper - you couldn't
remove its "stream" method etc.).
Hope this helps. (Unfortunately, I can't think of a code construct that would
works equally in both Rhino and Nashorn.)
Attila.
On Mar 8, 2014, at 10:25 PM, Walter Higgins <[email protected]> wrote:
> In Java 7 I can iterate over the properties/methods of a Java object using
> this notation...
>
> for (var p in javaObject) {
> print(p);
> }
>
> In java 8 this no longer works.
>
> for (var p in javaObject) {
> print(p);
> }
>
> ...doesn't result in the for loop block being executed (there are no
> properties).
>
> How can I iterate over the Java object properties in a consisted way
> between Java 6, 7 and 8?
>
> --
> Walter Higgins
> Mobile: (+353) 086 8511600
> Website: http://walterhiggins.net/