On 27/11/14 10:33, Attila Szegedi wrote:
Nashorn explicitly allows [] operator on java lists and it also supports for…in on them.
".length" is also supported since 8u20, see
<https://bugs.openjdk.java.net/browse/JDK-8039387>.
We indeed don't implicitly convert Lists into JS Array objects in Nashorn. The
reason is that JS Array has a Java array as backing storage; wrapping a large
list would incur a lot of copying.
To avoid the copying, could the Nashorn JS Array implementation be
changed so it backs either:
a) A Java Array (as it does currently) - this would the case if you
created the JS array directly in JS code.
b) A Java List - this would be the case if a List was passed from Java
to JS, providing the user with a JS array
Then we can have our cake and eat it? I.e. we have a real JS Array
object (not a half way house with some of the functions and properties
but not all), and no copying overhead.
You can use "Java.from(someObject.provideList())" to explicitly convert a
Java List to a JS array. We think it's better to provide an explicit conversion API than
incur a linear conversion cost whenever a List object passes into the JS context.
The Java.from created copy is shallow; if you have a List of Lists, the nested
List objects are not converted.
Typically you'll want to create a real Array if you want to use Array
functionality that points beyond [], .length, and for…in, e.g. JS Array
comprehension operations (arguably, we *could* implement even those so that
Array.prototype.forEach.call(javaList, ...) works as expected, but we aren't
there yet.)
Attila.
On Nov 27, 2014, at 10:41 AM, Tim Fox <timvo...@gmail.com> wrote:
Hello again,
I am a bit confused about how Lists passed from Java into JS are converted.
I have a Java class as follows:
public class SomeClass {
public List<String> provideList() {
List<String> list = new ArrayList<>();
list.add("foo");
list.add("bar");
return list;
}
}
I call this from JavaScript:
var io = Packages.io;
var someObject = new io.vertx.scratchpad.SomeClass();
var arr = someObject.provideList();
console.log(arr[0]); // prints: foo
console.log(typeof arr.length); // undefined
console.log(arr instanceof Array); // false
I was under the impression that Nashorn automatically converted Java lists
passed into JS into JS Arrays.
The object arr returned in some ways resembles a JavaScript array - the operators [] and
[]= work on it, however it doesn't have the array property "length" and it's
not an instanceof Array.
Can anyone clarify to me what this object is? Any reason why Nashorn doesn't
just wrap it as a real JS Array?
Cheers