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是一个函数,它会对对象本身调用一次,然后对对象中的每个属性各调用一次。

  1. var a = {
  2. "b" : 42,
  3. "c" : 42,
  4. "d" : [1,2,3]
  5. }
  6. JSON.stringify(a,["b,""c"]) //"{"b":42,"c":"42"}"
  7. JSON.stringify(a,function(k,v) {
  8. if(k !== "c") {
  9. return v
  10. }
  11. }) //"{"b":42,"d":[1,2,3]}"

2.space:用来指定输出的缩进格式,space是正整数时指定每一级缩进的字符数,它还可以是字符串,表示缩进用指定的字符串,而非空格

1.1.2.2 序列化规则顺序

  1. 如果被序列化的对象存在toJSON方法并且能通过它取得有效的值,则调用该方法。否则,返回对象本身。
  2. 如果提供了第二个参数,应用这个数组或函数过滤器,传入函数过滤器的值是第1步返回的值。
  3. 对第二部返回的每个值进行响应的序列化。
  4. 如果提供了第三个参数,执行响应的格式化。

    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()的方式。

  1. var timestamp = +new Date()
  2. timestamp = new Date().getTime()
  3. timestamp = Date.now()

2.2 显式解析数字字符串 -parseInt

解析允许字符串中含有非数字字符,解析按从左到右的顺序,如果遇到非数字字符就停止。
parseInt(value)该方法针对的是字符串值,非字符串的参数首先会被转换为字符串.ES5之前的parseInt有一个bug,如果没有第二个参数指定转换的基数,parseInt会根据字符串的第一个字符决定基数。

2.3 显示转换为布尔值

从非布尔值强制转换为布尔值可以通过Boolean方法,不过最常用的方法是!!
**

3. 隐式强制类型转换

3.1 字符串和数字之间的隐式强制转换

对于+二元运算符,如果某个操作数是字符串或能够通过以下步骤(ToPrimitive)转换为字符串的话,执行字符串连接,否则执行数字加法

  1. var a = [1,2]
  2. var b = [3,4]
  3. var c = 42
  4. a + b //"1,23,4"
  5. c + "" //"42"

注意:c + “”和String(c)有个细微的区别,a + “”会对a调用valueOf方法或toString方法,而String(a)直接调用了toString

  1. var a= {
  2. valueOf:function() { return 42; },
  3. toString:function() { return 4; }
  4. }
  5. a + "" //"42"
  6. String(a) //"4"

3.2 布尔值到数字的强制转换

+二元操作符对于数字和布尔类型值的处理规则是,布尔值会转换为数字,true转换为1,false转换为0。

应用场景:如果需要判断多个参数,需要判断其中有且仅有一个true,这时就可以使用从布尔值到数字的强制类型转换

  1. function onlyOne() {
  2. let sum = [].reduce.call(arguments,function(prev,next) {
  3. return next + prev
  4. },0)
  5. return sum === 1
  6. }

3.3 && 和||

3.3.3 定义

在JavaScript中&& 和 || 返回的并不是布尔值。他们返回的是两个操作数中的一个(且仅一个),即选择两个操作数的一个,然后返回它的值。具体规则如下:

  1. ||和&&首先会对第一个操作数执行条件判断,如果其不是布尔值就先进行ToBoolean转换,然后再执行条件判断
  2. ||:如果条件判断结果为true就返回第一个操作数,false就返回第二个操作数
  3. &&:如果条件判断为true就返回第二个操作数,false返回第一个操作数的值。

3.3.4 应用场景

  1. ||常用于合并合并运算(检查变量是否为空,如果为空赋予默认值)
  2. && 守护运算符,前边的表达式为后边的表达式把关,如果前一个条件成立,才执行后边的表达式 ```javascript function foo() { console.log(a) }

var a = 42 a && foo()

  1. <a name="bt3o3"></a>
  2. ## 3.4 symbol
  3. ES6允许符号到字符串的显示转换(String(...)),隐式(a + "")转换会产生错误,符号不能被转换为数字,但是可以转换为布尔值(true)
  4. <a name="Ym5du"></a>
  5. # 4. == 和 ===
  6. 本质区别,==允许在相等比较中进行强制类型转换,而===不允许。<br />==在比较两个不同类型值时会发生隐式强制类型转换,会将其中之一或两者都转换为相同的类型后再进行比较。
  7. <a name="w2Rfn"></a>
  8. ## 4.1 字符串和数字的相等比较
  9. 字符串隐式强制转换为数字然后与另一个数字比较
  10. <a name="o0EbH"></a>
  11. ## 4.2 其他类型与布尔类型的相等比较
  12. 布尔类型会先强制转换为数字类型,然后根据==两边的变量类型再做转换。
  13. ```javascript
  14. var x = true
  15. var y = "42"
  16. x == y //false
  17. //1.首先x会被转成数字类型,也就是1
  18. //2.然后根据数字类型和字符串==转换规则,y会被转换为数字42,结果为 1 == 42 false

注意:不要使用 “a == true” 和 “b==false”,对于变量本身做布尔判断,直接使用!!显式强转换 或者Boolean(…)
_

4.3 null和undefined之间的相等比较

在==中null和undefined相等(它们也与自身相等),除此之外其他值都不和它们相等

  1. var a = doSomething()
  2. //条件判断a == null只有在doSomething返回null和undefined时成立,除此之其他值都不成立,包括0 false ""这样的假值
  3. if(a == null) {
  4. ...
  5. }

4.4 对象和非对象之间的相等比较

对象(对象/函数/数组)和标量基本类型(字符串/数字/布尔值)之间的相等比较采用以下规则:
1.对象与布尔值,布尔值会先转换为数字,然后对象调用ToPrimitive()
2.对象与字符串或数字,对象调用ToPrimitive,然后根据情况再做转换
3.基本类型装箱成对象与基本类型比较时,会对其进行拆箱

  1. var a = 'abc'
  2. var b = Object(a)
  3. a === b //false
  4. a == b //true

针对上述第三条有几种特殊情况如下:

  1. var a = null
  2. var b = Object(a)
  3. a == b //false
  4. var c = undefined
  5. var d = Object(c)
  6. c == d //false
  7. var e = NaN
  8. var f = Object(e)
  9. e == f //false

4.5 对象与对象比较

如果两个操作数都是对象,则比较它们是不是同一个对象,如果两个操作数指向同一个对象,返回true,否则返回false