一、类型介绍
1、原始值
包含:undefined、null、布尔值、数字和字符串
2、对象
包含:数组和函数
3、包装对象
String、Number、Boolean
// 一个字符串、数字和布尔值 let s = "test", n = 1, b = true; let S = new String(s); // 一个字符串对象 let N = new Number(n); // 一个数值对象 let B = new Boolean(b); // 一个布尔值对象 // S, N, B即为包装对象
二、类型间转换规则
1、js类型转换:
2、对象转换为原始值
- 对象到布尔值的转换:所有的对象(包括数组和函数)都转换为true。也含包装对象,如 new Boolean(false)是一个对象,它将转换为true。
- 对象到字符串:一般调用对象 toString() 方法,没有则调用valueOf()方法,否则抛出异常。
- 对象转数字:一般先调用valueOf()方法,没有则调用toString()方法,否则抛出异常。如果返回的原始值不为数字,则有需要会转换成数字。
三、比较原则
- 原始值的比较是值得比较:只有在它们的值相等时它们才相等。
- 对象比较是引用的比较,不是值得比较。
四、相等比较
1、严格相等运算符 “===” 首先计算其操作数的值,然后比较这两个值,比较过程没有任何类型转换:
- 如果两个值类型不相同,则它们不相等。
- 如果两个值都是null或者都是undefined,则它们不相等(实测相等)。
- 如果两个值都是布尔值true或都是布尔值false,则它们相等。
- 如果其中一个值是NaN,或者两个值都是NaN,则它们不相等。NaN和其他任何值都是不相等的,包括它本身!
- 如果两个值为数字且数值相等,则它们相等。如果一个值为0,另一个值为-0,则它们同样相等。
- 如果两个值为字符串,且所含的对应位上的16位数完全相等,则它们相等。如果它们的长度或内容不同,则它们不等。
如果两个引用值指向同一个对象、数组或函数,则它们是相等的。如果指向不同的对象,则它们是不等的,尽管两个对象具有完全一样的属性。
2、相等运算符 “==” 和恒等运算符类似,但相等运算符的比较并不严格。如果两个操作数不是同一类型,那么相等运算符会尝试进行一些类型转换,然后进行比较:
- 如果两个操作数的类型相同,则和上文所述的严格相等的比较规则一样。如果严格相等,那么比较结果为相等。如果它们不严格相等,则比较结果为不相等。
- 如果两个操作数类型不同,“==” 相等操作符也可能会认为它们相等。检测相等将会遵守如下规则和类型转换:
- 如果一个值是null,另一个是undefined,则它们相等。
- 如果一个值是数字,另一个是字符串,则将字符串转换为数字,然后使用转换后的值进行比较。
- 如果其中一个值是true,则将其转换为1再进行比较。
- 如果一个值是对象,另一个值是数字或字符串,则将对象转换为原始值,然后再进行比较。
- 其他不同类型之间的比较均不相等。
五、比较操作符
比较操作符的操作数可能是任意类型。然而,只有数字和字符串才能真正执行比较操作,因此那些不是数字和字符串的操作数都将进行类型转换,类型转换的规则如下:
如果操作数为对象,则先把对象转换为原始值。调用valueOf()或者toString()方法。
在对象转换为原始值之后,如果两个数都是字符串,那么将依照字母表的顺序对两个字符串进行比较。
在对象转换为原始值之后,如果至少有一个操作数不是字符串,那么两个操作数都将转换为数字进行数值比较。
六、总结
1、基本类型比较,按值比较
- 恒等"===",类型相同,然后值比较
- 相等"==",类型可以不同,值转换比较
2、对象与对象比较
- 恒等"=" 和 相等 "" , 指向内存空间相同则相等
- 比较操作, 先转换成基本类型,然后比较,如果转换后有一个操作数不是字符串,则转换成数字进行比较
3、对象与基本类型比较
- 恒等"===" 因为不指向相同的内存空间,则不会相等。
- 相等 “==” 对象先转换成基本类型,然后比较,如果转换后有一个操作数不是字符串,则转换成数字进行比较
- 比较操作, 先转换成基本类型,然后比较,如果转换后有一个操作数不是字符串,则转换成数字进行比较
1、参考《JavaScript权威指南》