将值从一种类型转换为另外一种类型一般称为类型转换,这是显示的状况。隐式的状况称为强制类型转换,在JavaScript中存在不少隐式类型转换的状况javascript
6种原始类型(基本数据类型):前端
Object (引用类型):vue
基本类型(基本数值、基本数据类型)是一种既非对象也无方法的数据。在 JavaScript中,共有6种基本类型:string,number,boolean,null,undefined,symbol (ECMAScript 6)。java
这里就要提到原生类型内建的包装对象,包括:node
在操做原始数据类型的属性和方法时,JS会自动将原始类型转换成一个对应的包装对象。此时该对象就拥有了属于它自己的一系列属性和方法。因此当咱们定义了一些基本数据类型,想访问其对应的属性或方法时,就须要将其转换为这个值的包装对象,然而现实中并不须要这么麻烦,这是由于JS运行的宿主对象(浏览器等)将会自动地包装基本类型值来知足这样的访问。因此我认为所谓JS万物皆对象,或许只是自动的实现了一些隐式的转换。react
关于 === 和 == 比较操做符的不一样,在比较浅显的认知中,全等操做符(===)会比较类型,而比较运算符(==)则不会比较类型。 然而咱们看一下其在MDN中的定义:webpack
全等操做符(===)比较两个值是否相等,两个被比较的值在比较前都不进行隐式类型转换。 相等操做符(==)比较两个值是否相等,在比较前将两个被比较的值转换为相同类型。web
由此得出这两个操做符最大的不一样,就是在比较前是否会进行隐式类型转换。算法
咱们也常常会见过不少隐式转换比较的题目,如:数组
undefined == null //true
[] == [] //false
[] == ![] //true
{} == !{} //false
![] == {} //false
[] == !{} //true
[1,2] == ![1] //false
复制代码
因此上述的是依据什么规则如何进行转换?在ECMA文档中的抽象相等比较算法具体描述了以下规则。
在比较x == y,其中 x 和 y 是值,结果返回 true 或 false 。比较规则以下:
a. 若是x的类型为Undefined,返回true。
b. 若是x的类型为Null,返回true。
c. 若是x的类型为Number,则以下:
i. 若是 x 为 NaN, 返回 false.(NaN == NaN 为false)
ii. 若是 y 为 NaN, 返回 false.
iii. 若是 x 和 y 的值相同, 返回 true.
iv. 若是x为+0,y为−0,返回 true.
v. 若是x为−0,y为+0,返回 true.
其余返回 false.
d. 若是x是string类型,那么假如x和y是彻底相同的字符序列(相同的长度和相应位置的相同字符),则返回true。不然,返回false。
e. 若是x是布尔类型,假如x和y都为true或都为false,则返回true。不然,返回false。
f. 若是x和y引用同一对象,则返回true。不然,返回false。
复制代码
2. 若是x为null,y为undefined,则返回true。
3. 若是x为undefined,y为null,则返回true。(其他的任何类型与undefined和null相比都为false)
4. 若是x是数字类型,y是字符串类型,则返回x == ToNumber(y)的比较结果.
5. 若是x是字符串类型,y是数字类型,则返回ToNumber(x) == y的比较结果.
6. 若是x是布尔类型,则返回ToNumber(x)==y的比较结果.
7. 若是y是布尔类型,则返回x == ToNumber(y)的比较结果.
8. 若是x是字符串或数字类型,y 是对象类型,返回比较结果x== ToPrimitive(y)。
9. 若是x是对象类型,y是字符串或数字类型,返回比较结果ToPrimitive(x)==y。
10. 其余则返回false
复制代码
抽象操做ToNumber将非数字值转换为数字类型。
抽象操做ToPrimitive将引用类型转为基本数据类型。
JS引擎内部转换为原始值ToPrimitive(obj,preferredType)函数接受两个参数,第一个obj为被转换的对象,第二个preferredType为但愿转换成的类型(默认为空,接受的值为Number或String)
在执行ToPrimitive(obj,preferredType)时若是第二个参数为空而且obj为Date的实例时,此时preferredType会被设置为String,其余状况下preferredType都会被设置为Number若是preferredType为Number。
转换为Number数字类型的过程为首先调用obj.valueOf(),若是执行结果是基本数值类型就返回该值,不然就调用obj.toString(),返回该字符串类型值。
转换为String数字类型的过程为首先调用obj.toString(),若是执行结果是基本数值类型就返回该值,不然就调用obj.valueOf(),返回该字符串类型值。
上述规则总结起来基本就是:
在上图测试结果总结以下:
由此能够看出,对象、数组、日期类型最后基本都被转换为字符串类型。因此咱们姑且能够将ToPrimitive看作将引用类型最后都转换为字符串类型。
抽象操做ToBoolean将转为布尔类型。
对于布尔类型转换来讲,假值(undefined、null、false、+0、-0、NaN、"")会被转换为false,除假值外的全部值都会被转换成true。
抽象操做ToString将转为字符串类型。
对于字符串类型也比较好理解,大部分的基本数据类型转换为字符类型时,基本就是在它基础上加了引号这么直观,比较特殊的就是+0、0、-0它们几个都会被转成相同的'0',还有那些极小和极大的数字将会转换为指数形式的字符串来表现,而引用类型转换成字符串的时候也跟它们ToPrimitive时候的规则一致(见上文ToPrimitive)。