为什么 Kotlin/JS Return === 的结果与 Kotlin/JVM 不同?
Why Does Kotlin/JS Return Different Results for === Than Does Kotlin/JVM?
鉴于此代码:
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
对象)。
为什么我会根据运行时环境得到不同的结果?
在JavaScript中既有原始字符串也有字符串对象(参见https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String中的"Distinction between string primitives and String objects")。
Kotlin/JS 中的 value.toUpperCase().toLowerCase() === value
编译为 JavaScript 中的 value.toUpperCase().toLowerCase() === value
(您可以通过查看 https://try.kotlinlang.org/ 中的 "Generated JavaScript code" 选项卡来验证). value.toUpperCase().toLowerCase()
returns 原始字符串。 ===
在原始字符串上是正常相等。
这是因为运行时如何处理它。
在 JVM 上,==
映射到 equals
,===
映射到 ==
(身份检查),如 . Meanwhile, JavaScript's 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 编译为原始字符串,而不是字符串对象。因此,当您处理原始字符串时,JS 中的 ===
将 return 为真。
鉴于此代码:
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
对象)。
为什么我会根据运行时环境得到不同的结果?
在JavaScript中既有原始字符串也有字符串对象(参见https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String中的"Distinction between string primitives and String objects")。
Kotlin/JS 中的value.toUpperCase().toLowerCase() === value
编译为 JavaScript 中的 value.toUpperCase().toLowerCase() === value
(您可以通过查看 https://try.kotlinlang.org/ 中的 "Generated JavaScript code" 选项卡来验证). value.toUpperCase().toLowerCase()
returns 原始字符串。 ===
在原始字符串上是正常相等。
这是因为运行时如何处理它。
在 JVM 上,==
映射到 equals
,===
映射到 ==
(身份检查),如
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 编译为原始字符串,而不是字符串对象。因此,当您处理原始字符串时,JS 中的 ===
将 return 为真。