It doesn’t… Null is its own type in JS. The typeof operator returns the string “object” for a null value as per http://es5.github.io/#x11.4.3 <http://es5.github.io/#x11.4.3>, but that’s (weird JS) special-casing. Internally, Null is a type with one value, null.
> On 17 Aug 2016, at 07:56, Hannes Wallnöfer <hannes.wallnoe...@oracle.com> > wrote: > > It’s unfortunate JS considers null to be of type ‚object‘. I think that in > most practical circumstances and definitely when a number comes from a Java > primitive you can omit the null check as Java primitives can’t be null, > though. > > Hannes > > >> Am 16.08.2016 um 16:16 schrieb João Paulo Varandas <joaovaran...@inpaas.com>: >> >> Hi Hannes. >> >> Thanks for reviewing this. Seeing it from this perspective: >> >> Longs are just like JS Number wrappers. >> >> Made me believe the situation was not that bad too. Telling developers to >> 'unwrap' numbers using " x = Number(x); " would not be a bad idea. >> >> With that in mind, any number comparison would have to be made unwrapping >> data first ... But, we would also need to test nulls first, because: >> >> While "null == 0" yields false, and obviusly "null === 0" yields false. >> Number(null) === Number(0) would yield true. >> >> Thus, we would need: >> >> function unwrapNumber(x) { >> return x == null ? null : Number(x); >> } >> >> And also, to tell developers to call unwrapNumber() everytime they need to >> compare a Number ... >> >> I don't know if you agree with me, but now I see this as an anti-pattern. >> >> >> --- >> >> Anyway... It seems that all the fuzz is because of that "bug" with Long >> numbers and double. And I'm sorry that I did not look further into that >> issue. >> >> Maybe we should look further into that, and try to make that any number >> below Number.MAX_SAFE_INTEGER (9007199254740991), work the way is expected >> inside JS evaluations ... >> >> >> >> >> >> >> >> >> >> João Paulo Varandas >> +55 11 99889-2321 >> joaovaran...@inpaas.com >> >> >> 2016-08-16 6:23 GMT-03:00 Hannes Wallnöfer <hannes.wallnoe...@oracle.com>: >> After exploring various options I don’t think there’s anything we can do to >> go back and treat longs like numbers in Nashorn. >> >> The ECMA spec is quite clear that there are numbers and object, and >> comparison of the latter is by reference, not value. So having some kind of >> in-between states is not really an option. Making longs numbers again would >> be quite a small and harmless change within the language (without reverting >> to longs as internal data type). Precision would be lowered to doubles for >> large longs, but that wouldn’t be a problem for most users. >> >> However, the problems starts where longs as numbers inherit from >> Number.prototype. Of course, all methods in Number.prototype are specified >> for double values, and the toString methods collides with toString in >> java.lang.Long. Having a toString method that rounds large longs to the >> nearest double value is a no-go. Nor is extending all methods in >> Number.prototype to handle longs are viable options. >> >> There is one issue we need to fix to improve handling of longs and other >> instances of java.lang.Number though (thanks to Attila for first pointing >> this out): Currently, java.lang.Numbers not treated as numbers in the >> ToPrimitive operation with Number hint. This means less-than/greater-than >> operators will treat those number objects as strings instead of converting >> to double. I filed a bug for this, and will back port it to JDK 8u: >> >> https://bugs.openjdk.java.net/browse/JDK-8163945 >> >> All things considered, there are some things that make me think the >> situation is not as bad as some seem to believe. For one, the new treatment >> of Longs (with the fix for the bug above) is consistent with how JavaScript >> Number objects/wrappers are treated. Comparing two Number wrappers for the >> same value will also evaluate to false with both == and === operators, while >> comparing them to the primitive number with == will evaluate to true. >> >> new Number(1) == new Number(1) // false >> new Number(1) === new Number(1) // false >> new Number(1) == 1 // true >> new Number(1) === 1 // false >> >> So Longs are just like JS Number wrappers. They are object wrappers for >> numeric values. If needed they can easily converted to primitive numbers by >> calling the global Number() function without „new“ keyword, eg: >> >> if (typeof x === „object“) >> x = Number(x); >> >> This is a common pattern in JavaScript even without Java longs, so I think >> it’s acceptable. >> >> Hannes >> >> >>> Am 05.08.2016 um 15:45 schrieb Hannes Wallnöfer >>> <hannes.wallnoe...@oracle.com>: >>> >>> Hi Joao Paulo, >>> >>> thanks for the report. >>> >>> We do realize that this change caused problems for a lot of people, and we >>> are sorry for that, and thinking how we can improve things. >>> >>> I still think we were right to remove longs as internal number >>> representation. But maybe we went to far with this, and should allow people >>> to deal with longs as numbers, assuming they are all right with an eventual >>> loss of presentation. >>> >>> This needs some discussion and thinking and experimentation. I’ll get back >>> to you after the weekend. >>> >>> Hannes >>> >>> >>> >>>> Am 05.08.2016 um 04:40 schrieb João Paulo Varandas >>>> <joaovaran...@inpaas.com>: >>>> >>>> By the way, I just found out some bugs filed about Long objects: >>>> https://bugs.openjdk.java.net/browse/JDK-8162771 >>>> https://bugs.openjdk.java.net/browse/JDK-8161665 >>>> >>>> And a twitter discussion: >>>> https://twitter.com/provegard/status/755010492112986112 >>>> >>>> I'd like to bring this up again if we have more room for discussion ... >>>> -- >>>> >>>> 2 Long values returned from a database and sent to a javascript evaluation >>>> code can't be compared the way it should in JavaScript... If I have some >>>> validation code, I don't know if the source is some JavaScript input >>>> (number), or the source is a database query (object/Long/Integer/Double). >>>> >>>> It's really hard to decide when sometimes x==y should be compared as >>>> x.equals(y) and sometimes not... and sometimes, at the same point in code >>>> I should do a lot of conditional operations, to resolve a simple >>>> comparison... and that comparison does not work if the data source is a >>>> Java object or a JavaScript object. >>>> >>>> The problem with the current solution is that comparison between different >>>> types would never work ... >>>> >>>> Seeing that >>>> jjs> new java.lang.Long(2147483648) == "2147483648" >>>> returns true >>>> >>>> But >>>> jjs> new java.lang.Long(2147483648) == new java.lang.Long(2147483648) >>>> returns false >>>> >>>> Is something really hard to accept ... >>>> And that "equals" approach will work ONLY if I compare Long to Long. And I >>>> see this as a regression when talking about evaluating JavaScript code. >>>> >>>> >>>> >>>> Sorry about the long post, but I would really appreciate if we could >>>> revalidate this and think about what the current situation represents from >>>> ecmascript's point of view. >>>> >>>> >>>> >>>> >>>> >>>> -08-04 22:43 GMT-03:00 João Paulo Varandas <joaovaran...@inpaas.com>: >>>> Sorry Tomas. >>>> >>>> Either you did not read the message(which would be indeed a beginner's >>>> mistake), or you are misleading the discussion. >>>> >>>> What you said, about equality and references would be true if we were >>>> talking about Java code. This is jdk8-nashorn's mailing list and I'm >>>> talking about JavaScript evaluation inside the JVM. >>>> >>>> >>>> Comparison operators inside the script engine follow JavaScript rules and >>>> not Java rules. >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> >>>> João Paulo Varandas >>>> +55 11 99889-2321 >>>> joaovaran...@inpaas.com >>>> >>>> >>>> 2016-08-04 20:08 GMT-03:00 Tomáš Zíma <to...@tzima.cz>: >>>> A classical beginner's mistake. You are using Java objects and comparing >>>> references, not the values, so this is expected behavior. Simply compare >>>> the objects using equals(). >>>> >>>> >>>> On 4.8.2016 15:48, João Paulo Varandas wrote: >>>> Hi guys! >>>> >>>> It seems that version 1.8.0_101 has a bug in equality for same java data >>>> types (java.lang.Long). >>>> >>>> Check that: >>>> jjs> new java.lang.Long(10) == new java.lang.Long(10) >>>> false >>>> >>>> Oops!? >>>> >>>> See the gist: >>>> https://gist.github.com/joaovarandas/51567bd3b576d48a4c574d60d5a60ba3 >>>> >>>> The results for all types should be ... >>>> == true >>>> === true >>>> equals true >>>> >>>> But for java.lang.Long and java.math.BigDecimal: >>>> == false >>>> === false >>>> equals true >>>> >>>> Maybe we could expand the test to other classes too, but the issue ... >>>> - It does happen in 1.8.0_101. >>>> - It does not 1.8.0_91. >>>> - It does happen with other classes (BigDecimal). >>>> - It does not happen with String. >>>> - It does not happen with Integer. >>>> >>>> >>>> I understand this is not an expected behavior. For now I'm rolling back >>>> to 1.8.0_91 in my environments. >>>> >>>> >>>> >>>> Do you me to file a bug? >>>> >>>> Thanks >>>> J >>>> >>>> >>>> >>>> >>>> >>>> >>>> "Esta mensagem, incluindo seus anexos, pode conter informacoes >>>> confidenciais e privilegiadas. >>>> Se voce a recebeu por engano, solicitamos que a apague e avise o remetente >>>> imediatamente. >>>> Opinioes ou informacoes aqui contidas nao refletem necessariamente a >>>> posicao oficial da Plusoft." >>>> >>>> "Antes de imprimir, pense em sua responsabilidade e compromisso com o MEIO >>>> AMBIENTE" >>> >> >> >> >> "Esta mensagem, incluindo seus anexos, pode conter informacoes confidenciais >> e privilegiadas. >> Se voce a recebeu por engano, solicitamos que a apague e avise o remetente >> imediatamente. >> Opinioes ou informacoes aqui contidas nao refletem necessariamente a posicao >> oficial da Plusoft." >> >> "Antes de imprimir, pense em sua responsabilidade e compromisso com o MEIO >> AMBIENTE" >> >