Confusing ScriptObjectMirror size() vs mirror.get("length")

Sundararajan Athijegannathan sundararajan.athijegannathan at oracle.com
Thu Dec 1 06:40:46 UTC 2016


I think this is not a bug. "length" is not the same as number of 
properties in an object. For example, if you try this:

var a = [3, 5, 66];
a.foo = "nar";
for (var i = 0; i < a.length; i++)
    print(a[i]);

"length" is 3 [and not 4].  keySet size is the number of "keys" 
(properties). You've to get "length" property of the array.

-Sundar

On 01/12/16, 1:32 AM, Art Fiedler wrote:
> @Sundararajan
>
> When looping an array in javascript I would typically do something like
> this...
>
>      for(var i = 0; i<  arr.length; i++) {
>          console.log('Index: ' + i + ' = ' + arr[i]);
>      }
>
> When looping a javascript array using the ScriptObjectMirror I would
> initially think to use the same syntax, however I would swap .length with
> .size() since that method is available.
>
> .size() however is not the same as .length in this case. I'm not saying
> that is a bug, just noting the confusion it could cause when/if someone
> write's a java loop like that and in the future they run into an undefined
> item in the middle of the javascript array. See this example...
>
> Thanks,
> Arthur Fiedler
>
>      public static void main(String[] args) throws Exception {
>          NashornScriptEngineFactory factory = new
> NashornScriptEngineFactory();
>          ScriptEngine scriptEngine = factory.getScriptEngine();
>          scriptEngine.eval(
>                  "globalArray = new Array(3);\n" +
>                  "globalArray[0] = 'line1';\n"+
>                  "globalArray[2] = 'line3';\n"); // Note index 1 was skipped
>          ScriptObjectMirror array =
> (ScriptObjectMirror)scriptEngine.get("globalArray");
>          System.out.println("entrySet.size(): " + array.entrySet().size());
>          System.out.println("keySet.size(): " + array.keySet().size());
>          System.out.println("values.size(): " + array.values().size());
>          System.out.println("length: " + array.get("length"));
>          System.out.println("size(): " + array.size());
>          for(int i = 0; i<  array.size(); i++) {
>              System.out.println("Index: " + i);
>              String iStr = String.valueOf(i);
>              System.out.println("    Get('"+iStr+"'): " + array.get(iStr));
>          }
>          System.out.println("what happened to index 2?? oops!");
>      }
>      /*
>      entrySet.size(): 2
>      keySet.size(): 2
>      values.size(): 2
>      length: 3
>      size(): 2
>      Index: 0
>          Get('0'): line1
>      Index: 1
>          Get('1'): null
>      what happened to index 2?? oops!
>      */


More information about the nashorn-dev mailing list