62.==和===&toString和valueOf

150 阅读4分钟

==和===

对于==的判断会先进行强制类型转换在确定操作数是否相等

  • 布尔值转成数值再进行比较,false:0,true:1

  • 字符串和数值,将字符串转成数值

  • 对象和操作数,调用对象的valueOf方法获取其原始值再比较

    • 数组和值,会先转成值再比较,与字符串比较会先转成字符串再比较
    • 引用和值,会把引用类型转成原始类型在比较
    • 值和值,比较类型再比较值大小
    • 字符串和数字,字符串转为数值在比较
    • 对象和非对象,非对象为string或number,则返回ToPrimitive(对象)==非对象的结果;

    ToPrimitive方法参数是原始类型则直接返回;

    如果是对象类型,调用valueOf方法,如果是原始值再进行原始类型转换和大小对比;如果不是原始值则调用toString,且结果为原始值则进行原始类型比较,如果不是原始值则抛出错误。

ToPrimitive(input,preferedType)

preferedType:默认为Number

日期会被认为是字符串。

执行Number的步骤:

  • Input为原始值,直接返会
  • input是对象,调用对象的valueOf方法,结果是原始值,则返回结果
  • 否则,调用对象的.toString()方法,如果结果是原始值,则返回结果
  • 否则:抛出错误

执行string的步骤:

  • Input为原始值,直接返会
  • 调用对象的.toString()方法,如果结果是原始值,则返回结果
  • 调用对象的valueOf方法,结果是原始值,则返回结果
  • 否则:抛出错误

比较规则:

  • null==undefined::true null == 任意值 : false undefined == 任意值: false null===undefined: false
  • null和undefined不能转换为其他类型的值再进行比较
  • NaN==任意值:false NaN!=任意值 :true NaN==NaN :false
  • 都是对象,对比是否是同一个对象

[]==![]

  • 运算符优先级高会先计算![]
  • []=true,!true=false 因此表达式被转换为:[]==false
  • Boolean与any,因此表达式被转换为:[]==0
  • 此时变为object与0的比较,调用object.valueOf其结果还是为valueOf([].valueOf()==[]),因此表达式被转换为:[]==0
  • 再调用[].toString结果为'',''转成number=0,因此表达式被转换为:0==0
  • 结果为true

valueof和toString

  • value返回得是原始类型得值,没有原始对象返回的对象本身。toString将内容输出为字符串方法,每个对象都有自己不同得实现

  • undefined和null都没有toString()和valueOf()方法

  • Date类型的toString返回表示时间的字符串;valueOf返回的是现在到1970年1月1日的毫秒数

  • Number类型的toString方法可以接收转换基数,返回不同进制的字符串形式的数值;valueOf方法无法接收转换基数

Type测试toString()valueOf
function(function a (){}).toString()'function a (){}'function a(){},函数本身
Object({}).toString()[object Object]、返回"[object 对象类型名称]"{}、对象本身
Date(new Date()).toString()Fri Jan 28 2022 09:00:12 GMT+0800 (中国标准时间),日期的文本表示时间戳,毫秒数
String('a').toString()"a",返回string对象的值"a",字符串值
Number(1).toString()"1",返回字符串的数字表示,可以指定进制1,数字值
Boolean(true).toString()"true",返回"true"or "false"true,boolean值
undefinedundefined.toString()报错报错
nullnull.toString()报错报错
Array([1,2].toString())"1,2"相当于join方法[1,2],数组本身

2022.2.23 补充

undefined.toString()和null.toString()方法会报错的原因,是因为其内部调用了toObject方法

undefined.valueOf()和null.valueOf()方法会报错的原因,是因为其内部调用了toObject方法

toObject方法原始类型返回其值,对象类型返回参数。

对象.toString为什么会返回"[object Object]"?

首先判断是否为undefined和null,不为undefined和null获取其参数的类型,其参数类型为Object,因此返回"[object Object]"。

ECMA262 toString方法判断逻辑:

  • 如果value为undefined,返回"[object Undefined]"
  • 如果value为null,返回"[object Null]"
  • 让O成为ToObject(this.value)的执行结果
  • IsArray(O)判断执行结果
  • 设置tag为ArrayArgumentsFunctionErrorBooleanNumberStringDateRegExpObject
  • 如果Type[tag]不是String,则设置tag为以上的某一种
  • 返回"[object tag]"

valueOf方法返回调用toObject的结果。

参考1:==比较 参考2:ToPrimitive 参考3:toString