1. 抽象值操作
ToString ToNumber ToBoolean ToPrimitive转换规则
1.1 toString
1.1.1 转换规则
值类型 | 转换规则 | 备注 |
---|---|---|
null | “null” | |
undefined | “undefined” | |
布尔值 | “true”或者”false” | |
数字 | 数字的字符串形式 | 极小或极大的数字使用指数形式 |
对象 | 调用抽象操作ToPrimitive | toPrimitive首先检查该值是否有valueOf()方法,如果有并且返回基本类型值,就是用该值进行强制类型转换,如果没有就是用toString,如果valueOf()和toString()均不返回基本类型值,会抛出TypeError错误 |
数组 | 将所有单元字符串化后用逗号拼接 | 数组默认的toString方法经过了重新定义 |
1.1.2 JSON字符串化 -JSON.stringify
所有安全的JSON值都可以使用JSON.stringify字符串化,所谓安全的JSON值是不包含 undefined function symbol 及循环引用的对象。
JSON.stringify在对象中遇到undefined function 和symbol时会自动将其忽略,在数组中则会返回null(以保证单元位置不变),对包含循环应用的对象执行JSON.stringify会出错。
如果对象定义了toJSON方法,JSON字符串化时会首先调用该方法,然后用它的返回值进行序列化,如果要对含有非法JSON值的对象序列化或者对象中的某些值无法被序列化时,就需要定义toJSON方法来返回一个安全的JSON值
**
1.1.2.1 语法
JSON.stringify(object,replacer,space)
1.replacer:它可以是一个数组或函数,用来指定对象序列化过程中哪些属性应该被处理。如果replacer是一个数组,包含要序列化处理的对象属性名,其他的属性会被忽略,如果replacer是一个函数,它会对对象本身调用一次,然后对对象中的每个属性各调用一次。
var a = {
"b" : 42,
"c" : 42,
"d" : [1,2,3]
}
JSON.stringify(a,["b,""c"]) //"{"b":42,"c":"42"}"
JSON.stringify(a,function(k,v) {
if(k !== "c") {
return v
}
}) //"{"b":42,"d":[1,2,3]}"
2.space:用来指定输出的缩进格式,space是正整数时指定每一级缩进的字符数,它还可以是字符串,表示缩进用指定的字符串,而非空格
1.1.2.2 序列化规则顺序
- 如果被序列化的对象存在toJSON方法并且能通过它取得有效的值,则调用该方法。否则,返回对象本身。
- 如果提供了第二个参数,应用这个数组或函数过滤器,传入函数过滤器的值是第1步返回的值。
- 对第二部返回的每个值进行响应的序列化。
- 如果提供了第三个参数,执行响应的格式化。
1.2 ToNumber
1.2.1 转换规则
| 值类型 | 转换规则 | 备注 | | —- | —- | —- | | null | 0 | | | undefined | NaN | | | 布尔值 | 1或0 | | | 对象 | 遵循ToPrimitive操作 | |
1.3 ToBoolean
假值列表
- undefined
- null
- false
- +0 -0和NaN
- “”
2. 显式强制类型转换
2.1 字符串和数字
字符串和数字之间的转换是通过String()和Number()两个内建函数,前边没有new,并不创建封装对象。
+运算符的一元形式(只有一个操作数)会显示的将字符串转换为数字,而非数字加法运算
**
2.1.1 +或-一元操作符
+一元操作符会像Number转型函数一样对这个值进行转换,布尔false和true转换为0和1,字符串按照特殊的规则进行解析,而对象先调用它们的valueOf方法或toString方法,再转换得到的值。
在将一元减操作符应用与数值时,该值会变成负数,而当应用于非数值时,一元-和一元+遵循相同的规则,最后再将得到的数值转换为负数。
应用场景:可以通过一元+运算符将日期对象强制转换为数字,返回结果是Unix时间戳,也可以使用new Date().getTime()或者Date.now()的方式。
var timestamp = +new Date()
timestamp = new Date().getTime()
timestamp = Date.now()
2.2 显式解析数字字符串 -parseInt
解析允许字符串中含有非数字字符,解析按从左到右的顺序,如果遇到非数字字符就停止。
parseInt(value)该方法针对的是字符串值,非字符串的参数首先会被转换为字符串.ES5之前的parseInt有一个bug,如果没有第二个参数指定转换的基数,parseInt会根据字符串的第一个字符决定基数。
2.3 显示转换为布尔值
从非布尔值强制转换为布尔值可以通过Boolean方法,不过最常用的方法是!!
**
3. 隐式强制类型转换
3.1 字符串和数字之间的隐式强制转换
对于+二元运算符,如果某个操作数是字符串或能够通过以下步骤(ToPrimitive)转换为字符串的话,执行字符串连接,否则执行数字加法
var a = [1,2]
var b = [3,4]
var c = 42
a + b //"1,23,4"
c + "" //"42"
注意:c + “”和String(c)有个细微的区别,a + “”会对a调用valueOf方法或toString方法,而String(a)直接调用了toString
var a= {
valueOf:function() { return 42; },
toString:function() { return 4; }
}
a + "" //"42"
String(a) //"4"
3.2 布尔值到数字的强制转换
+二元操作符对于数字和布尔类型值的处理规则是,布尔值会转换为数字,true转换为1,false转换为0。
应用场景:如果需要判断多个参数,需要判断其中有且仅有一个true,这时就可以使用从布尔值到数字的强制类型转换
function onlyOne() {
let sum = [].reduce.call(arguments,function(prev,next) {
return next + prev
},0)
return sum === 1
}
3.3 && 和||
3.3.3 定义
在JavaScript中&& 和 || 返回的并不是布尔值。他们返回的是两个操作数中的一个(且仅一个),即选择两个操作数的一个,然后返回它的值。具体规则如下:
- ||和&&首先会对第一个操作数执行条件判断,如果其不是布尔值就先进行ToBoolean转换,然后再执行条件判断
- ||:如果条件判断结果为true就返回第一个操作数,false就返回第二个操作数
- &&:如果条件判断为true就返回第二个操作数,false返回第一个操作数的值。
3.3.4 应用场景
- ||常用于合并合并运算(检查变量是否为空,如果为空赋予默认值)
- && 守护运算符,前边的表达式为后边的表达式把关,如果前一个条件成立,才执行后边的表达式 ```javascript function foo() { console.log(a) }
var a = 42 a && foo()
<a name="bt3o3"></a>
## 3.4 symbol
ES6允许符号到字符串的显示转换(String(...)),隐式(a + "")转换会产生错误,符号不能被转换为数字,但是可以转换为布尔值(true)
<a name="Ym5du"></a>
# 4. == 和 ===
本质区别,==允许在相等比较中进行强制类型转换,而===不允许。<br />==在比较两个不同类型值时会发生隐式强制类型转换,会将其中之一或两者都转换为相同的类型后再进行比较。
<a name="w2Rfn"></a>
## 4.1 字符串和数字的相等比较
字符串隐式强制转换为数字然后与另一个数字比较
<a name="o0EbH"></a>
## 4.2 其他类型与布尔类型的相等比较
布尔类型会先强制转换为数字类型,然后根据==两边的变量类型再做转换。
```javascript
var x = true
var y = "42"
x == y //false
//1.首先x会被转成数字类型,也就是1
//2.然后根据数字类型和字符串==转换规则,y会被转换为数字42,结果为 1 == 42 false
注意:不要使用 “a == true” 和 “b==false”,对于变量本身做布尔判断,直接使用!!显式强转换 或者Boolean(…)
_
4.3 null和undefined之间的相等比较
在==中null和undefined相等(它们也与自身相等),除此之外其他值都不和它们相等
var a = doSomething()
//条件判断a == null只有在doSomething返回null和undefined时成立,除此之其他值都不成立,包括0 false ""这样的假值
if(a == null) {
...
}
4.4 对象和非对象之间的相等比较
对象(对象/函数/数组)和标量基本类型(字符串/数字/布尔值)之间的相等比较采用以下规则:
1.对象与布尔值,布尔值会先转换为数字,然后对象调用ToPrimitive()
2.对象与字符串或数字,对象调用ToPrimitive,然后根据情况再做转换
3.基本类型装箱成对象与基本类型比较时,会对其进行拆箱
var a = 'abc'
var b = Object(a)
a === b //false
a == b //true
针对上述第三条有几种特殊情况如下:
var a = null
var b = Object(a)
a == b //false
var c = undefined
var d = Object(c)
c == d //false
var e = NaN
var f = Object(e)
e == f //false
4.5 对象与对象比较
如果两个操作数都是对象,则比较它们是不是同一个对象,如果两个操作数指向同一个对象,返回true,否则返回false