private static String js_join ( Context cx , Scriptable thisObj , Object [ ] args ) { long llength = getLengthProperty ( cx , thisObj , false ) ; int length = ( int ) llength ; if ( llength != length ) { throw Context . reportRuntimeError1 ( "msg.arraylength.too.big" , String . valueOf ( llength ) ) ; } // if no args, use "," as separator String separator = ( args . length < 1 || args [ 0 ] == Undefined . instance ) ? "," : ScriptRuntime . toString ( args [ 0 ] ) ; if ( thisObj instanceof NativeArray ) { NativeArray na = ( NativeArray ) thisObj ; if ( na . denseOnly ) { StringBuilder sb = new StringBuilder ( ) ; for ( int i = 0 ; i < length ; i ++ ) { if ( i != 0 ) { sb . append ( separator ) ; } if ( i < na . dense . length ) { Object temp = na . dense [ i ] ; if ( temp != null && temp != Undefined . instance && temp != Scriptable . NOT_FOUND ) { sb . append ( ScriptRuntime . toString ( temp ) ) ; } } } return sb . toString ( ) ; } } if ( length == 0 ) { return "" ; } String [ ] buf = new String [ length ] ; int total_size = 0 ; for ( int i = 0 ; i != length ; i ++ ) { Object temp = getElem ( cx , thisObj , i ) ; if ( temp != null && temp != Undefined . instance ) { String str = ScriptRuntime . toString ( temp ) ; total_size += str . length ( ) ; buf [ i ] = str ; } } total_size += ( length - 1 ) * separator . length ( ) ; StringBuilder sb = new StringBuilder ( total_size ) ; for ( int i = 0 ; i != length ; i ++ ) { if ( i != 0 ) { sb . append ( separator ) ; } String str = buf [ i ] ; if ( str != null ) { // str == null for undefined or null sb . append ( str ) ; } } return sb . toString ( ) ; }
See ECMA 15 . 4 . 4 . 3