We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
我无意在Reddit上找到了这个JavaScript meme,它是我见过最好的抽象。
Reddit
JavaScript meme
你可以通过运行开发者工具来运行(图中)的每行代码来验证此关系的准确性。结果并不令人惊讶,但仍然令人失望。
当然,这个小实验触发了我的兴趣...
凭借经验,我学会了接受JavaScript这滑稽的一面,同时感受它的松散。尽管如此,这个事件的细节仍然让我感到困惑。
JavaScript
正如 Kyle Simpson所说...
Kyle Simpson
"不管怎么说,我认为任何人都不会真正了解JS"
当这些案例出现时,最好查阅源代码--构建JavaScript的官方ECMAScript规范。
有了这个规范,让我们深刻理解这里发生了什么。
如果你在开发者控制台上运行0 == "0",为什么它返回true?
0 == "0"
true
0是一个数字,然后"0"是一个字符串,它们永远不应该相同的!大多数编程语言都遵守它。例如,Java中的0 == "0",会返回下面这个:
0
"0"
Java
error: incomparable types: int and String
这很有道理。如果要比较Java中的int和String,必须先把它们转换为相同的类型。
int
String
但这是JavaScript,你们呀!
当你通过==比较两个值时,其中一个值可能受到强制转换。
==
强制 - 自动将值从一种类型转换为另一种类型。
这里的自动是关键词。JavaScript不是在显式转换你的类型,而是在幕后帮你完成。
如果你有目的地利用它,这很方便,但如果你不知道它的含义,则可能有害。
这是关于它的官方ECMAScript语言规范。 我会解释相关部分:
If x is Number and y is String, return x == ToNumber(y)
译:如果 x 是数字类型,y 是字符串类型,将 y 转换成数字类型与 x 作比较后返回
所以我们的例子0 == "0":
因为 0 是一个数字类型,"0" 是一个字符串类型,则返回 0 == ToNumber("0")
我们的字符串"0"已经被秘密转换成数字0,现在我们有一个匹配了!
0 == "0" // true // The second 0 became a number! // so 0 equals 0 is true....
奇怪吧?好好习惯它,我们接着说~
这种强制不仅仅限制于字符串,数字或布尔值等基本数据类型。这是我们的下一个比较:
0 == [] // true // What happened...?
再次被强制了!我将解释规范的相关部分:
If x is String or Number and y is Object, return x == ToPrimitive(y)
译:如果 x 是字符串或数字类型,然后 y 是对象类型,将 y 转换为基本数据类型与 x 作比较后返回
这里有三件事:
抱歉,刷新了你的认知。
再次根据规范,JS首先寻找一个对象的toString方法来强制转换它。
toString
在数组的情况下,toString连接其所有元素并将它们作为字符串返回。
[1, 2, 3].toString() // "1,2,3" ['hello', 'world'].toString() // "hello,world"
因为我们的数组是空的,我们没内容去拼接!所以...
[].toString() // ""
规范中的ToPrimitive将空数组转换成空字符串。相关的参考在这里和这里,方便你查阅(或解决疑惑)。
ToPrimitive
你不能把这些东西搞定。现在我们已经将数组强制变成"",我们又回到了第一个算法(规范)...
""
所以0==""
0==""
Since 0 is Number and "" is String, return 0 == ToNumber("")
ToNumber("")返回 0 。
ToNumber("")
因此,再一次是0==0...
0==0
0 == "0" // true
因为被强制转换成这个0 == ToNumber("0")。
0 == ToNumber("0")
0 == [] // true
因为强制转换执行两次:
ToPrimitive([])
所以,告诉我...根据上面的规则,下面将返回什么?
"0" == []
FALSE! 正确。
如果你明白规则,这部分是有意义的。
下面是我们的比较:
"0" == [] // false
再次参考规范:
那就意味着...
Since "0" is String and [] is Object, return x == ToPrimitive([])
"0" == ""
"0"和""都是字符串类型,所以JavaScript不需要再强制转换了。这就是为什么得到结果为false的原因。
false
使用三重等号(===),然后晚上睡个好觉。
0 === "0" // false 0 === [] // false "0" === [] // false
它完全避免强制转换,所以我猜它也更有效率!
但是('==='对于)性能的提升几乎毫无意义。真正的胜利是你在代码中增加的信心,使得额外的击打键盘完全值得。
更多的内容,请戳我的博客进行了解,能留个star就更好了💨
The text was updated successfully, but these errors were encountered:
https://felix-kling.de/js-loose-comparison/
Sorry, something went wrong.
@zhangenming 棒
No branches or pull requests
TLDR:强迫自己使用三重等号(===)
我无意在
Reddit
上找到了这个JavaScript meme
,它是我见过最好的抽象。你可以通过运行开发者工具来运行(图中)的每行代码来验证此关系的准确性。结果并不令人惊讶,但仍然令人失望。
当然,这个小实验触发了我的兴趣...
这是怎么发生的?
凭借经验,我学会了接受
JavaScript
这滑稽的一面,同时感受它的松散。尽管如此,这个事件的细节仍然让我感到困惑。正如
Kyle Simpson
所说...当这些案例出现时,最好查阅源代码--构建JavaScript的官方ECMAScript规范。
有了这个规范,让我们深刻理解这里发生了什么。
板块1 - 引入强制
如果你在开发者控制台上运行
0 == "0"
,为什么它返回true
?0
是一个数字,然后"0"
是一个字符串,它们永远不应该相同的!大多数编程语言都遵守它。例如,Java
中的0 == "0"
,会返回下面这个:这很有道理。如果要比较
Java
中的int
和String
,必须先把它们转换为相同的类型。但这是
JavaScript
,你们呀!当你通过
==
比较两个值时,其中一个值可能受到强制转换。这里的自动是关键词。
JavaScript
不是在显式转换你的类型,而是在幕后帮你完成。如果你有目的地利用它,这很方便,但如果你不知道它的含义,则可能有害。
这是关于它的官方ECMAScript语言规范。 我会解释相关部分:
所以我们的例子
0 == "0"
:我们的字符串
"0"
已经被秘密转换成数字0
,现在我们有一个匹配了!奇怪吧?好好习惯它,我们接着说~
板块2 - 数组也被强制
这种强制不仅仅限制于字符串,数字或布尔值等基本数据类型。这是我们的下一个比较:
再次被强制了!我将解释规范的相关部分:
这里有三件事:
1.是的,数组是对象
抱歉,刷新了你的认知。
2.空数组变成空字符串
再次根据规范,JS首先寻找一个对象的
toString
方法来强制转换它。在数组的情况下,
toString
连接其所有元素并将它们作为字符串返回。因为我们的数组是空的,我们没内容去拼接!所以...
规范中的
ToPrimitive
将空数组转换成空字符串。相关的参考在这里和这里,方便你查阅(或解决疑惑)。3.空字符串然后变成0
你不能把这些东西搞定。现在我们已经将数组强制变成
""
,我们又回到了第一个算法(规范)...所以
0==""
ToNumber("")
返回 0 。因此,再一次是
0==0
...板块3 - 快速回顾
这是正确的
因为被强制转换成这个
0 == ToNumber("0")
。这也是正确的
因为强制转换执行两次:
ToPrimitive([])
转换为空字符串ToNumber("")
转换为 0 。所以,告诉我...根据上面的规则,下面将返回什么?
板块4 - FALSE!
FALSE! 正确。
如果你明白规则,这部分是有意义的。
下面是我们的比较:
再次参考规范:
那就意味着...
"0"
和""
都是字符串类型,所以JavaScript
不需要再强制转换了。这就是为什么得到结果为false
的原因。总结
使用三重等号(===),然后晚上睡个好觉。
它完全避免强制转换,所以我猜它也更有效率!
但是('==='对于)性能的提升几乎毫无意义。真正的胜利是你在代码中增加的信心,使得额外的击打键盘完全值得。
参考和后话
更多的内容,请戳我的博客进行了解,能留个star就更好了💨
The text was updated successfully, but these errors were encountered: