HaxeFoundation / haxe

Haxe - The Cross-Platform Toolkit
https://haxe.org
6.1k stars 647 forks source link

Inconsistency in comparing nullable strings in Javascript #9623

Open EddieCameron opened 4 years ago

EddieCameron commented 4 years ago

Haxe generally knows how to compare strings constructed with var myStringA = new String("blah") and strings constructed with `var myStringB = "blah", and will treat them equally.

However in a switch statement (at least in Javascript), these will not be equal:

        var dynamicString = new String("abc");
        trace(dynamicString == "abc");    // prints 'true'

        // this switch statement doesn't work as expected
        switch (dynamicString) {
            case "abc":
                trace("doesn't print");
            case "force js switch code":
                trace("---");
        }

        // these workarounds do work
        var abc = Std.string(dynamicString);
        switch (abc) {
            case "abc":
                trace("Does print");
            case "force js switch code":
                trace("---");
        }

        var abc2 = "abc";
        switch (dynamicString) {
            case abc2:
                trace("Does print");
            case "force js switch code":
                trace("---");
        }
EddieCameron commented 4 years ago

(I'm new to Haxe, please forgive my confusion about dynamic vs nullable terminology)

Simn commented 4 years ago

That's tragic, but I don't really see what we could do about it if JavaScript behaves like that...

nadako commented 4 years ago

Yeah it's a bit specific JS quirk. new String(...) "boxes" the string so it loses strict equality (which is used for switch in JS) with other strings. One solution would to add .toString() to the switch subjects that are String, but it looks pretty awkward and is really only ever needed for this particular edge-case.

Also FYI, case abc2: in this case is not what you think it is, it's a pattern variable capture, not a comparison against local variable named abc2.

EddieCameron commented 4 years ago

Ha, I thought case abc2 seemed unusual...

So if JS uses strict equality for all switch comparisons, would this happen with boxed basic types as well? Does haxe use non-strict comparison for any other types? (like how C# structs use member-wise equality)