==和===
对于==的判断会先进行强制类型转换在确定操作数是否相等
-
布尔值转成数值再进行比较,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值 |
undefined | undefined.toString() | 报错 | 报错 |
null | null.toString() | 报错 | 报错 |
Array | ([1,2].toString()) | "1,2"相当于join方法 | [1,2],数组本身 |
2022.2.23 补充
人生第一次读ECMA的文档,虽然比较难啃,但是比在网上查资料的效率高很多,最重要的是更加权威。里面一些因果讲的很清楚,自然而然一些疑惑就会解开了。
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为Array、Arguments、Function、Error、Boolean、Number、String、Date、RegExp、Object
- 如果Type[tag]不是String,则设置tag为以上的某一种
- 返回"[object tag]"
valueOf方法返回调用toObject的结果。
网友评论