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

Reply via email to