js为什么[]==![]是成立的吗
前言
js是一门弱类型的语言,它的强制类型转换的迷惑性也被人诟病,例如标题提到的一个小例子,我想可能很难再找到其他的语言,允许我们觉到一个值似乎既为真也为假。
其实现在规范更推荐js开发者们避免使用 == 这种会产生强制类型转换的语法,大家尽可能会用 === 来代替,我在工作中也确实如此。
这里涉及到强制类型转换的问题,由于js的类型设计如此,它并不是难用,而是容易出现让人难以理解的内容,所以被很多人诟病。其实遇到任何问题,第一时间不应该是回避,而是应该试着去了解它,理解了也就不会迷惑了。
我想你也想解除一下自己的迷惑吧?本文就来给介绍一下关于==的类型转换问题。
== 与 === 的区别
这时候,如果你有经验,你肯定会说:这个我知道,== 只判断值,=== 会同时判断值和类型
这么理解也许可以,但是严格来说,这句话不够准确,真正的区别应该是:== 在比较两个不同类型的值时会发生强制类型转换,而 === 不会
强制类型转换
然后怎么转换呢?记一下以下几点就完了。
前置条件是两者类型不同,
- 两者如果是表达式,先计算表达式。
- 两者中有一个是对象类型,则该对象类型执行ToPrimitive后再进行比较。
- 两者都是基本类型,判断类型是否相同,不同,则同时执行ToNumber后再比较。
- 特殊情况,null == underfined,两者在 == 比较中只与对方和自己本身相等。
ToPimitive:执行该对象的valueOf函数,如果结果为基本类型则直接返回,否则返回该对象的toString函数的执行结果。
ToNumber:转化为数字类型。
例子
ok,知道了以上的内容,我们来看看[]==![]发生了什么。
[] == ![] // 右边是表达式,先进行计算,[]的boolean值为true,所以![]则为false // ⬇⬇⬇ [] == false // 右边是基本类型,左边则是数组(对象类型),因此对左侧执行ToPrimitive // ⬇⬇⬇ // ToPrimitive执行过程 [].valueOf() // 结果为[],valueOf返回的仍然是原数组对象,非基本类型,执行ToString [].toString() // 结果为空字符串'',为字符串基本类型,返回 '' == false // 两边都为基本类型,类型仍然不同,两边同时执行ToNumber // ⬇⬇⬇ // 两边同时ToNumber转化为数字类型 Number('') // 0 Number(false) // 0 0 == 0 // true
哈哈哈,虽然很扯淡,但是结果就是这样的。
练习
试试,根据上方学习到的知识,能不能尝试让自己理解以下的等式为什么是true呢?
console.log('0' == false) // true console.log(0 == false) // true console.log('' == false) // true console.log([] == false) // true console.log('' == 0) // true console.log('' == []) // true console.log(0 == []) // true
特殊情况undefined==null
虽然两者都是基本类型,可是遇到它们时要特殊处理,不可以使用Number进行转换,两者在==中只与彼此和自身相等,因此进行上方步骤判断时,不要忘了遇到null和undefined,不要再继续转换了。
而且根据这个特殊性质,当我们需要判断一个值为undefined或者null时,完全可以简化判断,这不是很好吗?
if (res === undefined || res === null) { // ... } // 等同于 if (res == null) { // ... }
尾言
本文介绍了==的强制类型转换,虽然我知道这在工作中实用性不大,哈哈哈,不过就当是满足一下自己的求知欲吧。更多相关js []==![]内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
最新评论