Surprising Nashorn behavior for String methods

Emilian Bold emilian.bold at gmail.com
Mon Oct 17 05:48:26 UTC 2016


@Andreas: But Nashorn on JDK 8 does not implement ECMAScript 6.


--emi

On Mon, Oct 17, 2016 at 8:22 AM, Andreas Rieber <rieberandreas at gmail.com>
wrote:

> Hi Sundar,
>
> startsWith is part of ECMAScript:
>
> http://www.ecma-international.org/ecma-262/6.0/#sec-string.p
> rototype.startswith
>
> Not widely supported...
>
> cheers
> Andreas
>
>
>
> On 17/10/2016 06:48, Sundararajan Athijegannathan wrote:
>
>> Hi,
>>
>> "startsWith" is non-standard extension (actually, it is Java method)
>>
>> jjs> "hello".startsWith
>> [jdk.internal.dynalink.beans.OverloadedDynamicMethod
>> java.lang.String.startsWith]
>>
>> "startsWith" is not an ECMAScript standard specified property of
>> String.prototype.  In Nashorn, you can call methods of java.lang.String
>> on JS strings.  "split" is an ECMAScript standard specified property of
>> String.prototype and hence you find it as "function" valued property of
>> String.prototype.
>>
>> HTH,
>>
>> -Sundar
>>
>>
>> On 10/17/2016 2:20 AM, Esben Andreasen wrote:
>>
>>> Hi
>>>
>>> I am not sure if this is a bug or feature of the Nashorn engine. But
>>> it looks like some String-prototype methods are missing, yet the
>>> methods are somehow present when used in the right way.
>>>
>>> Minimal example: calling `startsWith` by using `call`:
>>>
>>> ```
>>> 1  $ jjs -v
>>> 2  jjs> String.prototype.startsWith.call('abc', 'ab')
>>> 3  <shell>:1 TypeError: Cannot read property "call" from undefined
>>> ```
>>>
>>> Expected behavior:
>>>
>>> Not a type error, for multiple reasons:
>>>
>>> 1. Other JavaScript engines do not throw a type error.
>>> 2. The equivalent code `"abc".startsWith("ab")` does not throw a type
>>> error.
>>>
>>>
>>> Further investigation:
>>>
>>> ```
>>>  1  $ jjs -v
>>>  2  nashorn 1.8.0_101
>>>  3  jjs> "abc".startsWith('ab')
>>>  4  true
>>>  5  jjs> "abc".startsWith
>>>  6  [jdk.internal.dynalink.beans.OverloadedDynamicMethod
>>>      boolean java.lang.String.startsWith(String,int)
>>>      boolean java.lang.String.startsWith(String)
>>>     ]
>>>  7  jjs> "abc".startsWith.call("abc", "ab")
>>>  8  <shell>:1 TypeError: "abc".startsWith.call is not a function
>>>  9  jjs> typeof String.prototype.startsWith
>>> 10  undefined
>>> 11  jjs> String.prototype.split.call("abc", "b")
>>> 12  a,c
>>> ```
>>>
>>> Interpretation:
>>>
>>> It looks like `startsWith` is not present on the String-prototype, yet
>>> it is present on the String-primitives. Other String-prototype methods
>>> (`split`) are however present.
>>>
>>> Further notes:
>>>
>>> This also applies to `String.prototype.endsWith`.
>>>
>>>
>>> Related bug/feature: primitive values are not wrapped properly:
>>>
>>> ```
>>> 1  $ jjs -v
>>> 2  jjs> typeof Object("abc").startsWith
>>> 3  undefined
>>> ```
>>>
>>
>>
>


More information about the nashorn-dev mailing list