We always have to shift our minds when developing web applications, because we use several programming languages for them. Currently I am using:
- Java
- EcmaScript (JavaScript, JS)
EcmaScript is a superset of JavaScript, so every JS source is also valid ES source, but not vice versa. Only "modern" HTML-5 browsers can interpret ES.
- TypeScript
TypeScript also is a superset of JavaScript, every JS source is valid TS, but not vice versa. You need a compiler to translate from TS to JS.
String Comparisons
I tried to find out whether string comparisons work the same in all three languages. There are two kinds of comparisons, that of identity
if (s == t)
and that of equality
if (s.equals(t))
This was Java code.
In JavaScript (and TypeScript) similar exists, for identity
if (s === t)
and equality (let's call it "JS equality":-)
if (s == t)
Mind that the use of ===
and !==
is strongly recommended,
because ==
and !=
have a
complicated conversion logic,
see "Hard and soft comparisons".
I will show this
gotcha in the following example.
Plain Strings and Objects
In the following example, I distinguish between plain strings like
s1 = "10";
and actually allocated string objects like
s2 = new String("20");
Both is possible in all three languages.
The Java compiler optimizes plain strings in a way that it puts all equal definitions into just one place. It doesn't do this for allocated string objects, because these are constructed at runtime.
Most likely the JavaScript interpreter does similar things. Let's try it out.
EcmaScript Example Source
Four strings are used for this test: s1
and t1
are plain strings,
s2
and t2
are string objects.
They get compared to each other using both identity- and equality-comparisons.
var s1 = "10"; var t1 = "10"; var s2 = new String("20"); var t2 = new String("20"); alert( "\n s1 === t1: "+(s1 === t1)+ "\n s1 == t1: "+(s1 == t1)+ "\n s2 === t2: "+(s2 === t2)+ "\n s2 == t2: "+(s2 == t2) );
You can try this out on JsFiddle web page.
Here comes the result:
s1 === t1: true s1 == t1: true s2 === t2: false s2 == t2: false
Line one is not intuitive: s1 === t1
, which is an identity comparison.
The programmer has written two different strings!
But mind the surprising equality comparison in line four:
new String("20")
is not equal tonew String("20")
in JS, and unfortunately also not in TS!
A strong motivation to avoid the new
operator.
TypeScript Example Source
Use the same source as for JS. You can try out on the TypeScript Playground. The result is the same as for JS.
Unfortunately TS does not fix these JS gotchas. Whatever surprise you experience on JS language level, you will have the same in TS.
Java Example Source
You need a Java development kit to try this out.
public class Test { public static void main(String[] args) { final String s1 = "10"; final String t1 = "10"; final String s2 = new String("20"); final String t2 = new String("20"); System.out.println( "\n s1 == t1: "+(s1 == t1)+ "\n s1 equals t1: "+s1.equals(t1)+ "\n s2 == t2: "+(s2 == t2)+ "\n s2 equals t2: "+s2.equals(t2) ); } }
Output is:
s1 == t1: true s1 equals t1: true s2 == t2: false s2 equals t2: true
Mind the correct equality comparison in line four, now it is true
as expected.
Line one and two are exactly the same as in JS, due to compiler-optimized strings.
Nevertheless the difference between plain strings and string objects is a little puzzling, surely it is not intuitive.
Resume
Although both Java and JS are C-style programming languages, there seems to have been no common sense about how to perform comparisons.
Why was it called JavaScript? I always call it JS, and I am glad about the renaming to EcmaScript. The name JavaScript makes newcomers believe it is a Java script-interpreter. What a mistake!
Keine Kommentare:
Kommentar veröffentlichen