几分钟带你了解面试必问的类型转换

前言

在JavaScript中,类型转换有着非常重要的作用,它可以帮助我们将一种数据类型转换为另一种数据类型,从而更好地处理和操作数据。并且,类型转换还可以帮助我们在不同的数据类型之间进行比较和运算,从而提高程序的灵活性和可维护性。

类型转换也是面试中经常被问到的问题,因为它涉及到 JavaScript 的基础知识和核心概念,能够很好地检验应聘者对 JavaScript 的理解和掌握程度。

显式类型转换

人为使用类型转换方式将一种数据类型转换为另一种数据类型。

转换为数值类型

通过调用Number()函数将特定的值转换成数值。

javascript 复制代码
console.log(Number(undefined))//NaN
console.log(Number(null))//0
console.log(Number(true))//1
console.log(Number(false))//0
console.log(Number(0))//0
console.log(Number('abc'))//NaN
console.log(Number('123'))//123
console.log(Number(''))//0
console.log(Number('123abc'))//NaN
console.log(Number('   '))//0
console.log(Number(' 1  2'))//NaN
  1. null转数值:参数为nll时,结果为0。
  2. undefined转数值:参数为undefined时,结果为NaN。
  3. 数值转数值:结果为原数值。
  4. 字符串转数值:
    • 如果参数为空字符串或是只有空格,结果为0;
    • 如果参数是由'数值'组成的字符串(如'-12'、'1.25'、'-0.123'等),结果为该字符串相应的数值;
    • 除了上两种情况,其余字符串转数值的结果都为NaN。
  5. 布尔值转数值:如果参数是true,结果为1;如果参数是false,结果为0。
  6. 对象转数值:下文详细描述。

我们总结到一张表上:

null undefined 数值 空字符串或只有空格的字符串 '数值'组成的字符串 其余字符串 true false
number 0 NaN 原数值 0 对应的数值 NaN 1 0

转换为字符串类型

通过调用String()函数将特定的值转换成字符串。

javascript 复制代码
console.log(String(null));//'null'
console.log(String(undefined));//'undefined'
console.log(String(true));//'true'
console.log(String(false));//'false'
console.log(String(0.123)); //'0.123'
console.log(String(-0.123));//'-0.123'
console.log(String(123));//'123'
  1. null转字符串:参数为nll时,结果为'null'。
  2. undefined转字符串:参数为undefined时,结果为'undefined'。
  3. 数值转字符串:参数为数值,结果为'数值'。
  4. 字符串转字符串:参数为字符串,结果为原字符串。
  5. 布尔值转字符串:如果参数是true,结果为'true';如果参数是false,结果为'false'。
  6. 对象转字符串:下文详细描述。

我们总结到一张表上:

null undefined 数值 字符串 true false
string 'null' 'undefined' '数值' 字符串 'true' 'false'

转换为布尔值类型

通过调用Boolean()函数将特定的值转换成布尔值。

JavaScript 复制代码
console.log(Boolean(1));//true
console.log(Boolean(-1));//true
console.log(Boolean(0));//false
console.log(Boolean(NaN));//false
console.log(Boolean(''));//false
console.log(Boolean('a'));//true
console.log(Boolean(undefined));//false
console.log(Boolean(null));//false
  1. null转布尔值:参数为nll时,结果为false。
  2. undefined转布尔值:参数为undefined时,结果为false。
  3. 数值转布尔值:如果参数为-0、+0或NaN时,结果为false;否则结果为true。
  4. 字符串转布尔值:如果参数为空字符串,结果为false;否则结果为true。
  5. 对象转布尔值:参数是对象,结果为true。
  6. 布尔值转布尔值:参数是布尔值,结果为传入的参数。

我们总结到一张表上:

null undefined -0、+0或NaN 除-0、0和NaN外的数字 空字符串 除了空字符串 对象 true false
boolean false false false true false true true true false

原始值转对象

原始值可以通过构造函数包装成对应的对象类型。

javascript 复制代码
console.log(typeof (new String('abc')));//object
console.log(typeof (new Number(123)));//object
console.log(typeof (new Boolean(true)));//object
console.log(typeof (new Boolean(false)));//object

由于nullundefined没有对应的构造函数,所有没有办法通过该方法转为对象。

我们直接上表:

字符串 数值 true false
object new String(字符串) new Number(数值) new Boolean(true) new Boolean(false)

隐式类型转换

不是人为对数据类型进行转换,而是在编译器或运行环境自动进行的类型转换。

对象转原始值类型

将对象转换为原始值类型,通常是通过抽象操作ToPrimitive完成的。

valueOf

valueOf() 用于返回对象的原始值,但是valueOf() 只适用于原始值的封装对象。当原始值的封装对象调用valueOf(),返回这个原始值的封装对象的原始值。

toString

toString() 方法用于返回对象的字符串表示形式,但是不同的对象调用toString()会有不一样的效果:

  1. 对于原始值的封装对象:调用toString()返回该原始值的字符串形式。
  2. 对于数组:调用toString()返回一个由数组元素组成的逗号分隔的字符串。
  3. 对于普通对象:调用toString()返回一个"[object Object]"的字符串。

ToPrimitive

为什么要突然聊起了toString()valueOf(),当然是为了给主角ToPrimitive()做铺垫。

ToPrimitive有两个参数,一个是要转换的值(input),一个是期待返回的基本类型(默认为number)。

ToPrimitive的具体执行过程:

  1. 如果input不是对象类型而是原始类型,就直接返回该原始类型。
  2. 如果input是对象类型,并且期待返回的基本类型是string
    • 首先调用对象的toString(),如果返回的结果是原始值就返回该原始值。
    • 如果没有 toString() 方法或调用对象的toString()返回的结果不是原始值,尝试调用valueOf(),如果返回的结果是原始值就返回该原始值。
    • 调用valueOf()返回的结果也不是原始值,则抛出错误。
  3. 如果input是对象类型,并且期待返回的基本类型是number
    • 首先调用对象的valueOf(),如果返回的结果是原始值,则对该原始值进行转换为number后返回。
    • 如果没有 valueOf() 方法或调用对象的valueOf()返回的结果不是原始值,尝试调用toString(),如果返回的结果是原始值,则对该原始值进行转换为number后返回。
    • 调用toString()返回的结果也不是原始值,则抛出错误。
  4. 如果没有指定期待返回的数据类型就默认为number;如果input是Date对象,则期待返回的数据类型会被设置为string

对象转布尔类型

当对象需要被转换为布尔类型时,几乎所有的对象都会被转换为true

eg:

javascript 复制代码
if([]){
    console.log('执行了')
}

if语句内部代码会执行吗?

当然会呀,因为数组转布尔值为true

一元操作符(+)

+ 作为一元操作符,它会尝试将后面的值进行数值转换。

eg1:

javascript 复制代码
let str = '123'
console.log(+str);//123

具体流程:

  1. JavaScript引擎识别到+是一个前置的运算符。
  2. 接下来,引擎会检查+操作符后面的操作数的类型。
  3. 因为+用于数值操作,引擎会尝试将+操作符后面的操作数转换为数值。(该过程相当于调用了Number()构造函数)

eg2:

javascript 复制代码
let obj = {}
console.log(+obj);//NaN

具体流程:

  1. JavaScript引擎识别到+是一个前置的运算符。
  2. 接下来,引擎会检查+操作符后面的操作数的类型。
  3. 因为+用于数值操作,引擎会尝试将+操作符后面的操作数转换为数值。
    • {}转换为数值会调用ToPrimitive方法,没有特别指定期待转的基本类型默认为number
    • 首先调用valueOf方法,空对象{}没有定义自己的valueOf()方法,所以它继承自Object.prototype.valueOf(),这个方法对于普通对象而言返回对象本身,依然是对象,并非原始值。
    • 因为valueOf()没有给出一个原始值,ToPrimitive会尝试调用对象的toString()方法,给到的结果是"[object Object]"字符串,转换为数值为NaN

eg3:

javascript 复制代码
let arr = []
console.log(+arr)

输出结果是什么呢?你来试试吧。

二元操作符(+)

+ 作为二元操作符,它会根据操作数的类型执行不同的操作。eg:左操作数+右操作数:

  1. 分别对左操作数和右操作数调用ToPrimitive转换为原始值类型。
    • 如果左操作数和右操作数中有一个是字符串,那么就将左操作数和右操作数都转换为字符串进行拼接。
    • 如果左操作数和右操作数都不是字符串,就将左操作数和右操作数都转换为数值进行相加。

eg:

javascript 复制代码
console.log({} + [])//'[object Object]' + '' ---> '[object Object]'

相等操作符(==)

在比较x==y时,有以下的执行方式:

  1. 如果x和y的类型相同:
    1. undefined==undefined--->true
    2. null==null--->true
    3. number==number进行下一步判断:
      • NaN==NaN-->false
      • 相同的值==相同的值-->true
      • +0==-0-->true
      • 其余都是false
    4. string==string
      • 相同字符串==相同字符串-->true
      • 否则为fasle
    5. boolean==boolean
      • true==true-->true
      • false==false->true
      • 否则为false
  2. 如果x和y类型不同:
    1. null==undefined-->true
    2. 如果x和y中有对象,则对该对象调用ToPrimitive()转换为原始值进行比较。
    3. 如果x和y中有布尔和字符串都转换为数值进行比较。

这是官方文档的介绍,可以参考一下。

严格相等操作符(===)

提到==,一定会联想到===

严格相等操作符 ===

  • 不进行类型转换===在比较前不进行任何类型转换。如果两个操作数的类型不同,直接判定它们不相等。
  • 比较规则:只有在两个操作数的类型和值都完全相等时,才认为它们相等。
相关推荐
喜欢猪猪13 分钟前
springcloud 面试经常被问问题
spring·spring cloud·面试
朝阳3915 分钟前
vue3【实战】来回拖拽放置图片
javascript·vue.js
不如喫茶去15 分钟前
VUE自定义新增、复制、删除dom元素
前端·javascript·vue.js
长而不宰18 分钟前
vue3+electron项目搭建,遇到的坑
前端·vue.js·electron
阿垚啊1 小时前
vue事件参数
前端·javascript·vue.js
加仑小铁1 小时前
【区分vue2和vue3下的element UI Dialog 对话框组件,分别详细介绍属性,事件,方法如何使用,并举例】
javascript·vue.js·ui
码农超哥同学1 小时前
Python面试题:请解释 `lambda` 函数是什么,并举一个例子
开发语言·python·面试·编程
邵泽明1 小时前
面试知识储备-SpringCloud
spring cloud·面试·职场和发展
过去式的美好2 小时前
vue前端通过sessionStorage缓存字典
前端·vue.js·缓存
skyshandianxia2 小时前
Java面试八股之MySQL中binlog的工作模式有哪些
java·开发语言·面试