[基础] JavaScript 类型转换及面试题

关于 JS 类型转换

JS 有六种基本数据类型:

  • number
  • string
  • boolean
  • undefined
  • null
  • symbol(ES6 新加入)

以及一种引用类型:

  • object

当这些不同类型的数据之间,需要通过逻辑操作符进行判断,或者进行运算操作时,就会触发 JS 的隐性类型转换机制,对不同类型的数据先进行转换操作,再运行相关逻辑。


类型转换规则

JS 种的类型转换,只有如下三种情况:

  • 转为布尔值
  • 转为数字
  • 转为字符串

以下是各种数据类型之间相互转换的表格:

原始值类型目标值类型结果
boolean布尔值本身值,false 就为 false ,true 就为 true
number布尔值0 和 NaN 为 false 否则都为 true
string布尔值除了空字符串为 false 其他都为 true
undefined、null布尔值false
symbol布尔值true
对象布尔值true
数组布尔值true

原始值类型目标值类型结果
boolean字符串true: 'true';false: 'false'
number字符串数字字符串
string字符串字符串本身值
undefined、null字符串抛错
symbol字符串symbol 字符串
对象字符串'[object Object]'
数组字符串空数组转为空字符串,否则转为由逗号拼接每一项的字符串

原始值类型目标值类型结果
boolean数字true 转换为 1,false 转换为 0
number数字数字本身
string数字除了都是数字组成的字符串,能转换成数字外,其他都是 NaN
null数字0
undefined数字NaN
symbol数字抛错
对象数字NaN
数组数字空数组转换为0;只有一项(数字)的数组转换为这个数字;只有一项(空字符串、undefined、null)的数组转换为0;除上述以外情况的数组转换为 NaN

触发 JS 隐式转换的先决条件

在下面两种情况下,将会触发 JS 的隐性类型转换机制。

  1. 当使用 ==&&|| 等逻辑操作符进行判断时
  2. 当使用 + - * / 四则运算符进行操作时

下面就 == 和四则运算两种情况,来分析一下内部的转化机制:



1. 使用 == 操作符进行判断时

先来看下在使用 == 进行判断时,隐式转换的内部机制,判断步骤如下:

两个操作数类型一样的情况:
  1. 如果两个操作数是同类基本类型值,则直接比较
  2. 如果两个操作数是同类引用类型值,则比较内存地址
两个操作数类型不一样的情况:
  1. 如果有一个操作数是布尔值,则将这个布尔值转换为数字再进行比较。
  2. 如果有一个操作数是字符串,另一个操作数是数字,则将字符串转换成数字再进行比较
  3. 如果有一个操作数是引用类型的值,则调用该实例的 valueOf 方法,如果得到的值不是基本类型的值,再调用该实例的 toString 方法,用得到的基本类型的值按照前面的规则进行匹配对比。

以上逻辑转换成流程图:

特殊情况:
  1. null == undefined 判断为 true
  2. nullundefined 无法转换为基本类型值
  3. NaN != NaN 判断为 true,事实上,NaN 更像一个特例,谁都不等于

2. 使用 + 进行判断时

  1. 两个操作数都为数字时直接运行加法操作
  2. 其他情况下,将两个操作数都转换成字符串,进行字符串拼接操作。

3. 使用除 + 号以外的四则运算符判断时

直接进行数学运算,行就行,不行就直接 NaN,简单粗暴。


类型转换的经典面试题目

  1. [] == ![] 输出结果是?
  2. {} == !{} 输出结果是?
  3. 1 + '1' 输出结果是?
  4. true + true 输出结果是?
  5. 4 + [] 输出结果是?
  6. 4 + {} 输出结果是?
  7. 4 + [1] 输出结果是?
  8. 4 + [1, 2, 3, 4] 输出结果是?
  9. 'a' + + 'b'输出结果是?

第一题的转化逻辑如下:

// 尝试判断,!运算符的优先级大于 ==,所以实际上这里还涉及到!的运算。
[] == ![]
// 将右边 ![] 进行转换
[] == false
// 隐式转换布尔值为数字
[] == 0
// 转换左边的 [],调用 [] 实例的 valueOf 方法
[] == 0
// valueOf 方法返回的不是基本类型值,再次调用 toString 方法
'' == 0
// 隐式转换字符串为数字
0 == 0
// 返回结果
true
复制代码

第二题的转化逻辑如下:

// 尝试判断,!运算符的优先级大于 ==,所以实际上这里还涉及到!的运算。
{} == !{}
// 将右边 !{} 进行转换 
{} == false
// 隐式转换布尔值为数字
{} == 0
// 转换左边的 {},调用 {} 实例的 valueOf 方法
{} == 0
// valueOf 方法返回的不是基本类型值,再次调用 toString 方法
'[object Object]' == 0
// 隐式转换字符串为数字
1 == 0
// 返回结果
false
复制代码

后面的题目:

// 第三题
1 + '1' == '1' + '1' == '11'
// 第四题
true + true == 1 + 1 == 2
// 第五题
4 + [] == '4' + '' == '4'
// 第六题
4 + {} == '4' + '[object Object]' == '4[object Object]'
// 第七题
4 + [1] == '4' + '1' == '41'
// 第八题
4 + [1, 2, 3, 4] == '4' + '1, 2, 3, 4' == '41,2,3,4'
// 第九题,稍微有点复杂,+'b'是被转换成了 NaN
'a' + + 'b' == 'a' + 'NaN' == 'aNaN'
复制代码

本文参考了一些别人的观点,再加上自己手动控制台打印认证,如果有错误,欢迎指出,我即时修改。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值