JavaScript|js有关 == 容易出错点


js有关 == 容易出错点

  • 前言
  • 案例
  • 案例解决
    • 1. 空字符串和0 相等
    • 2. 空数组和0 相等
    • 3.空对象和0 不相等
    • 4.undefined和0不相等、null 和0 不相等、 .undefined和null相等
    • 5.[]和[]不相等,{}和{}不相等
    • 6.[]和![]相等
    • 7.+'sss'和+'sss' 不相等
  • 总结

前言 在js中有关 == 的用法,看起来不难;但是很多细节不注意将很容易出错,而且比其他语言都容易出错。这也是js弱类型语言的特性。
案例 先来一组简单的,看一下是否遇到过相应的问题
console.log("" == 0)//true console.log([] == 0) //true console.log({} == 0) //false console.log(undefined == 0) //false console.log(null == 0) //false console.log(null == undefined) //true

再看一组有点难度的,看能否理解
console.log([] == [])//false console.log([] == ![]) //true console.log({} == {}) //false console.log({} == !{}) //false console.log(+'sss' == +'sss') //false

案例解决 【JavaScript|js有关 == 容易出错点】要弄懂这些结果就必须了解一下js == 表达式的底层处理机制 如下图
JavaScript|js有关 == 容易出错点
文章图片

如上图所示 先把上面11个案例一个一个对着跑一下
1. 空字符串和0 相等
console.log("" == 0)//true

带入上图公式第5行 x为字符串 y为数组 所以转化如下
console.log(Number('') == 0)//0==0 true

2. 空数组和0 相等
console.log([] == 0)//true

这里面就有一个ToPrimitive(抽象操作)知识点了
抽象操作 ToPrimitive
(参见 ES5 规范 9.1 节)会首先(通过内部操作 DefaultValue,参见 ES5 规范 8.12.8 节)检查该值是否有 valueOf() 方法。如果有并且返回基本类型值,就使用该值进行强制类型转换。如果没有就使用 toString() 的返回值(如果存在)来进行强制类型转换。如果 valueOf() 和 toString() 均不返回基本类型值,会产生 TypeError 错误。
大致意思就是把先进行valueOf()操作 返回的值是不是基本类型,不是基本类型 就进行toString()操作看返回是不是基本类型
上面的 [] == 0;
就要进行流程图的第10行 x typeof x 为object 执行ToPrimitive() 操作
console.log([].valueOf())//[] console.log([].toString())//""

可以得到结果时 [] 进行ToPrimitive() 得到的值为 “” 这样比较的 就是和案例1一样的返回为true
3.空对象和0 不相等
console.log({} == 0)//false

和上题一样当 对{}做ToPrimitive()操作
console.log([].valueOf())//{} console.log([].toString())//"[object Object]"

再进行比较的话就是 “[object Object]” == 0 字符串和数字比较 字符产进行tonumber操作返回false
4.undefined和0不相等、null 和0 不相等、 .undefined和null相等
console.log(undefined == 0)//false console.log(null == 0) //false console.log(null == undefined) //true

根据上图undefined 只和本身 或者null相等,其他都不相等
5.[]和[]不相等,{}和{}不相等
console.log([] == [])//false

看起来一样却不相等,根据上图和所有的比较模块都不符合最后返回false;
关于引用类型的比较要比较其地址是否相等,地址相等两个才相等。如下:
var a = []; var b = a; var c = a; console.log(b == c)//true

6.[]和![]相等
console.log([] == ![])//true

这个知识点就比较多了
  1. 运算符优先级
  2. !的用法
  3. ==的用法
    运算符优先级如下图:
    JavaScript|js有关 == 容易出错点
    文章图片
1.!的运算优先级比==高所以先执行![];
console.log(![])//false

![]为啥是false呢? 因为[] 是一个引用类型 他有一个引用地址。所以[] 为true;如下
if([]){ console.log('sss') } //sss

2.在执行 [] == false;
3.对[]进行ToPrimitive()操作 执行
console.log('' == false) // true

7.+'sss’和+‘sss’ 不相等
console.log(+'sss' == +'sss') //false

又是两个看起来一样的 这里其实用到了 下次我准备更新的js + 的用法
优先级+先执行 +"sss"执行结果为NaN
直接就是
JavaScript|js有关 == 容易出错点
文章图片

返回false。
总结 有关js == 用法的总结如下:
  • 都为引用类型比较时 比较其地址 地址一致则相等,否则不相等
  • 引用类型和其他类型比较时 先对引用类型做ToPrimitive()操作 再进行比较
  • 都为number类型时 有一个为NaN 返回false

    推荐阅读