前言
你是否也有同款疑问:js中‘2’-1,‘1’+1的结果分别是什么,你看完就能知道结果,并且知道原因。
一 . 原始类型间的相互转化
1.原始值转boolean
上述代码涵盖了原始值转boolean中各类情况,需要特别注意的是结果为的false情况:首先Boolean()默认值是false;除此之外传入0,false,undefined,null转化为boolean结果都是false,其他的均为true。
2.原始值转数字
上述结果中需要特别记忆的是字符串‘0’,undefined,和null;非‘0’数字字符串的结果是0,其他数字字符串是该数字,而其他字符串是NaN。
值得注意的是,Number()内部原理是调用了toNumber(value)方法,只不过这个方法我们不能用。这里仅做了解,在后面理解原理中需要用到。
3.原始值转字符串
结果显而易见。所有类型转换为字符串都使传入的值直接变成了字符串。
与Number()类似,Stirng()内部调用的是toString()方法,这个方法我们常常用到。
二.原始类型与引用类型的相互转化
1.原始值转对象
通过String() Number() Boolean()这三个构造函数就可以轻松地将原始值转化为对象,接下来我们以String为例:
大家有没有发现一个问题,通过上面三个构造函数new出来的对象并不能添加属性和方法,而我们自己定义的构造函数new出来的对象就可以添加属性和方法。根本原因就是通过这几个构造函数new出来的对象有个[[PrimitiveValue]]属性,这个属性就让这些对象被判定为原始类型,也就不能添加属性和方法。但是只有这种对象可以使用valueOf方法,使其变成原始类型。
2.对象转布尔
3.对象转字符串和数字
相较于其他转化,这个最为复杂,我们来了解一下这个转化内部的过程。 首先流程是Ojbject=>ToPrimitive(input, String)
ToPrimitive(obj, PreferredType)//第一个参数是要转换的值;第二个参数是需要转换成的类型,只有Number,String,Boolean.
ToPrimitive(obj, Number)
- 如果obj是基本类型,直接返回
- else,调用 valueOf 方法,如果得到一个原始类型,则返回
- else,调用 toString 方法,如果得到一个原始类型,则返回
- else if报错
ToPrimitive(obj, String)
- 如果obj是基本类型,直接返回
- else,调用 toString 方法,如果得到一个原始类型,则返回
- else,调用 valueOf 方法,如果得到一个原始类型,则返回
- else if报错
通过上述流程就可以使对象变成原始类型,接下来通过之前讲的原始值转字符串,数字就可以得出最终答案。
toString,valueOf不是本次类型转换的重点,大家会使用就可以了,下面是相关的表。
接下来就是两个例子运用了上面的规则。
Number([])
([]).value()//[]
([]).toString//''
Number('')//0
Number({})
({}).value()//[]
({}).toString//'[object Object]'
Number('[object Object]')//NaN
三. 操作符和隐式转换
关于1+‘1’等于什么相信大家都知道并使用过,等于‘11’,但是是为什么呢?
这是因为js是一种弱类型的编程语言,在进行上述操作时,会进行类型转换,而且是隐式转换,再在 + 操作符的一系列规则下,最终得出结果。
1.一元操作符 +
+['1']这个例子就是一元操作符 +
一元操作符 + 的规则就是让调用ToNumber(['1']),这也很好理解,毕竟 + 这种运算就是为数字而生的,所以就转换成数字。具体过程前面也讲了,Number(['1'])通过ToPrimitive(obj, Number)方法,使其变成字符串或者是数字,如果是字符串,则在多一步冲字符串转数字,最后的结果都是数字。
上面的例子的结果也就是数字1
再来一个例子+['1','2','3'],这个例子的结果或许与你想的不尽想同。结果可以放在评论区。
2. 二元操作符 +
v1 + v2
- lprim = ToPrimitive(v1)
- rprim = ToPrimitive(v2)
- 如果 lprim 是字符串或 rprim 是字符串,那么返回 ToString(lprim) 和 ToString(rprim)的拼接结果
- 返回 ToNumber(lprim) 和 ToNumber(rprim)的相加结果
这样1+‘1’的结果就显而易见了。
3. ==
x == y
1). 如果 x 和 y 是同一类型
(1). x 是 Undefined,返回true
(2). x 是 null,返回true
(3). x 是数字
1. x 是 NaN ,返回 false
(4). x和y指向同一个对象,返回true,否则返回false
2). null == undefined // true
3). 1 == 'h' // ToNumber('h')
4). false == '1' // ToNumber(false) ToNumber('1')
5). true == {a: 1} // ToPrimitive({a: 1})