为什么Kotlin / JS与===相比Kotlin / JVM返回不同的结果?

时间:2019-07-01 11:55:28

标签: kotlin kotlin-js

给出以下代码:

val value = "something"

println(value.toUpperCase().toLowerCase() == value)   // prints true
println(value.toUpperCase().toLowerCase() === value)  // prints false

在Kotlin / JVM 1.3.40上,我得到:

true
false

在Kotlin / JS 1.3.40上,我得到:

true
true

我希望两者都得到相同的结果,并且我希望整体获得Kotlin / JVM的结果(因为我应该有不同的String对象)。

为什么在运行时环境下会得到不同的结果?

2 个答案:

答案 0 :(得分:3)

这是因为运行时如何处理它。

在JVM上,==映射到equals,而===映射到==(身份检查),如here所述。同时,JavaScript的equals operators are weirder。如果您对代码进行反编译,则可以使用JS来实现:

kotlin.kotlin.io.output.flush();
if (typeof kotlin === 'undefined') { 
    throw new Error("Error loading module 'moduleId'. Its dependency 'kotlin' was not found. Please, check whether 'kotlin' is loaded prior to 'moduleId'."); 
}
var moduleId = function (_, Kotlin) { 
    'use strict'; 
    var equals = Kotlin.equals; 
    var println = Kotlin.kotlin.io.println_s8jyv4$; 
    function main(args) { 
        var value = 'something';
        println(equals(value.toUpperCase().toLowerCase(), value)); // NOTE: equals
        println(value.toUpperCase().toLowerCase() === value);      // NOTE: ===
    } 
    _.main_kand9s$ = main; 
    main([]); 
    Kotlin.defineModule('moduleId', _); 
    return _; 
}(typeof moduleId === 'undefined' ? {} : moduleId, kotlin); 
kotlin.kotlin.io.output.buffer;

现在,如果您考虑使用等效的Java代码(略微缩短且没有Kotlin):

public static void main(String []args){
    String value = "something";

    System.out.println(value.toUpperCase().toLowerCase().equals(value));
    System.out.println(value.toUpperCase().toLowerCase() == value);
}

toUpperCase().toLowerCase()创建一个新对象,该对象打破了is identity checking==比较。

===也被概述为身份检查a === b is true if a and b are strings that contain the same characters。从反编译的Kotlin代码可以看出,Kotlin.JS编译为原始Strings,而不是String对象。因此,当您处理原始字符串时,JS中的===将返回true。

答案 1 :(得分:1)

在JavaScript中,既有原始字符串也有字符串对象(例如,参见https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String中的“字符串原始类型和String对象之间的区别”)。

Kotlin / JS中的

value.toUpperCase().toLowerCase() === value会在JavaScript中编译为value.toUpperCase().toLowerCase() === value(正如您可以通过查看https://try.kotlinlang.org/上的“ Generate JavaScript code”标签来验证)。 value.toUpperCase().toLowerCase()返回原始字符串。原始字符串上的===是正常的相等性。