S01E03-数据类型转换

JavaScript 的数据类型转换,我们只讨论三种情况,分别是:

转Boolean类型

  1. Boolean类型只有两个值:true / false,以下2种情况下会转换为布尔类型:

    • 手动转
      • Boolean()
      • !(先转为布尔类型,再取反)
      • !!(两次取反,只剩下转布尔类型了)
    • 自动转
      在流程控制语句中(如 if 语句),会自动执行 Boolean() 转换。
  2. 哪些值可以转换为 false?

    规律:在 JS 中转换为 false 的,只有 null、undefined、空字符串、0 和 NaN 这五个值。

    1
    2
    3
    4
    Boolean(0)=>false
    Boolean([])=>true
    !0=>true
    !!0=>false
  3. 常见笔试题

    1
    2
    []==false //=>两边都转为数字再比较,true
    ![]==false //=>[]先转为Boolean类型,取反,true

转Number类型

转换规律:

  • 基本类型转换为数字,使用Number()
  • 引用类型转换为数字,先toString()转换为字符串,然后再将字符串Number()转换为数字

以下4种情况下会转换为数字:

隐式转:isNaN()

isNaN() 检测机制:首先检测当前的值是不是数字类型的,如果不是会先转换为数字类型的,然后再判断。

1
2
3
4
5
6
7
8
9
10
11
12
//=>语法:isNaN([value])
isNaN('13') =>false
isNaN('陈陈') =>true
isNaN(true) =>false
isNaN(false) =>false
isNaN(null) =>false
isNaN(undefined) =>true
isNaN({age:9}) =>true
isNaN([12,23]) =>true
isNaN([12]) =>false
isNaN(/^$/) =>true
isNaN(function(){}) =>true

这里有几个引用类型的需要注意一下:

1
2
3
4
5
6
7
8
9
10
[对象]
({}).toString() ->'[object Object]' ->NaN

[数组]
[].toString() ->''->0
[12,23].toString() ->'12,23' ->NaN
[12].toString() ->'12' ->12

[正则]
/^$/.toString() ->'/^$/' ->NaN

显式转:Number() / parseInt() / parseFloat()

  1. **Number()**:浏览器自动转换默认的方法

    遇见字符串有洁癖:如果字符串中出现任意一个非数字字符,结果则为NaN。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    [字符串]
    Number('')=>0
    Number(' ')=>0 //空格
    Number('\n')=>0 //换行符
    Number('\t')=>0 //制表符
    Number('13')=>13
    Number('13px')=>NaN
    Number('13.5')=>13.5
    Number('13.5.0')=>NaN
    [布尔]
    Number(true) =>1
    Number(false) =>0
    [其它]
    Number(null)=>0
    Number(undefined)=>NaN
  2. **parseInt()/parseFloat()**:专门用于将字符串转换为数值。

    规则:从字符串的最左边开始查找,遇到非有效字符查找结束。
    parseInt:整数部分
    parseFloat:小数部分(第二个小数点无效)

    1
    2
    3
    4
    5
    6
    7
    8
    [字符串]
    parseInt('')=>NaN(区别于Number
    parseInt('13.5px')=>13
    parseInt('width:13.5px')=>NaN
    parseInt('1px3')=>1
    parseFloat('13.5px')=>13.5
    parseFloat('5a-1')=>5
    parseFloat('5e-1')=>0.5 //=> ???

    parseInt()支持两个参数,parseInt(’10px’, 2 )输出什么?2

隐式转换:+ - / *

规律:在JS中,+ - * / % 都是数学运算

  • +号,遇到字符串,开始起拼接作用,没有遇到之前是数学运算
  • 除 + 以外,其它在运算时,如果有非数字类型的值,会先转换为Number类型(自动发生Number()转换),然后再进行运算。

需要注意的细节问题:

  • i++ 遇见数字型字符串,就是单纯的数学运算,已经摒弃掉字符串拼接的规则

我们来看一些栗子:

1
2
3
4
5
6
7
8
9
'3'-1 =>2
'3px'-1 =>NaN
2+'3px' =>'23px' 字符串拼接
5+2+'3px'+1 =>'73px1'

var i='3';
i=i+1; =>'31'
i+=1; =>'31'
i++; =>4 //注意

思考题

1
2
3
4
5
6
7
8
9
var num = '10';
if (num == 10) {
num++;
} else if (num == 5) {
num--;
} else {
num = 0;
}
console.log(num); //=>11

“==”比较,两边多数会转换为Number类型

如果“==”两边的数据类型不相同,会首先进行强制类型转换,转换为相同类型再比较。

三种特殊情况:

  1. NaN
  2. null 和 undefined
    1
    2
    null == undefined //=>true
    null === undefined //=>false
  3. 对象 == 对象
    对象操作的是引用地址,因此判断两个引用地址是否指向同一个对象
    1
    2
    3
    4
    5
    {name:'xxx'}=={name:'xxx'} //=>false
    []==[] //=>false
    var obj1={};
    var obj2=obj1;
    obj1==obj2 //=>true

除了上边的三种特殊情况,两边只要不是数字类型的,都转换为数字类型,比如:

1
2
3
4
5
6
7
1==true //=>true
1==false //=>false
2==true //=>false 规律不要混淆,这里是把true变为数字1
[]==true //false 都转换为数字 0==1
[]==false //true 都转换为数字 0==0
![]==true //false
![]==false //true 先算![],把数组转换为布尔取反=>false

转String类型

toString()/ String() / toFixed() / join() 等方法

  1. toString()/ String()
    除了对象,都是你理解的转换结果,只要是普通对象,最后结果都是’[object Object]’。
    栗子:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    1 ->'1'
    NaN ->'NaN'
    null ->'null'
    [] ->''
    [13] ->'13'
    [12,23] ->'12,23'

    // 【对象】
    {name:'xxx'} ->'[object Object]'
    {} ->'[object Object]'
  2. toFixed()
    1
    2
    var n = Math.PI;//=>获取圆周率:
    n.toFixed(2);//=>'3.14'
  3. join()
    1
    2
    var ary = [12,23,34];
    ary.join('+');//=>'12+23+34'

alert() / confirm() / prompt() / document.write() 等输出内容的方法

这里有一个

  • alert(a++) =>是先执行 alert(a),然后 a 再自增 1
  • alert(++a) =>是先 a 自增 1,然后再执行 alert(a)
1
2
3
let a = 1;
alert(a++);//=>'1'
console.log(a);//=>2

同理:

1
2
3
let a = 1;
console.log(a++);//=>1
console.log(a);//=>2

“+”拼接字符串时

规律:当“+”连接的表达式中出现字符串时,开始拼接,前边的是数学运算

1
2
1+true //=>2 数学运算
'1'+true //=>'1true' 字符串拼接

思考题

1
2
3
12+true+false+null+undefined+[]+'陈'+null+undefin
ed+[]+true
=>'NaN陈nullundefinedtrue'

这里需要注意的是:

引用类型参与’+’运算
比如数组、对象(注意:对象要加括号),虽然没有看见字符串,但是当引用类型转换为数字时,首先会转换为字符串,所以'+'起的是字符串拼接的作用。

1
2
3
[12]+10 //=>'1210' 
({})+10 //=>"[object Object]10"
[]+10 //=>"10"

特殊情况{}+任意数据类型
=>根本就不是数学运算,也不是字符串拼接,它是两部分代码
=>实际操作的是后边的数据,会执行Number()转换为数字类型

1
2
3
4
5
6
7
8
9
10
{}+10 //=>10
// {} 代表一个代码块(块级作用域),严格写法:{}; +10;
// +10 才是我们的操作

// more
{}+'' //=>0
{}+[] //=>0
{}+null //=>0
{}+undefined //=>NaN
{}+{} //=>"[object Object][object Object]

给对象设置属性名时

对象的属性只能是数字或者字符串,如果不是字符串,首先转换为字符串,然后再
以这个字符串为 key 存储到对象中。

结束

重学 JS 系列 预计 25 篇左右,这是一个旨在帮助大家,其实也是帮助我自己捋顺 JavaScript 底层知识的系列。主要包括变量和类型、执行上下文、作用域及闭包、原型和继承、单线程和异步、JS Web API、渲染和优化几个部分,将重点讲解如执行上下文、作用域、闭包、this、call、apply、bind、原型、继承、Event-loop、宏任务和微任务等比较难懂的部分。让我们一起拥抱整个 JavaScript 吧。

作者

ZhangLK

发布于

2021-01-10

更新于

2023-07-05

许可协议