JS中的数据类型转换与判断,一篇带你全搞定

JS中的数据类型转换与判断,一篇带你全搞定

技术博客 admin 516 浏览

如果我们每天都用的数据类型不会判断的话 ,那和看见女神不想知道她名字有什么区别,看到数据类型不会转换的话,那和不想和女神在一起的咸鱼有什么区别。那么今天这篇文章,我将和你一起,从认识女神到和她在一起的方法,帮你全部搞定。

一、数据类型的种类

在JavaScript中,数据类型可分为两大类:原始数据类型(Primitive Data Types)和引用数据类型(Reference Data Types)。

  • 原始数据类型
ini
复制代码
let str = 'hello' let num = 123 let flag = false let un = undefined let nu = null ...
  • 引用数据类型
csharp
复制代码
let obj = {} let arr = [] function foo(){} ...

注: 其中undefinednull是比较难分清楚的,当你的钱包里没有钱的时候,那就是null,但你连钱包都没有的话,则为undefined

官方是这么定义它们的:undefined 是一个原始值,表示变量已被声明但没有被赋值,或者访问了一个不存在的属性。它代表的是一个“缺少值”的状态。null 也是一个原始值,它代表的是一个刻意的空值或者表示一个对象应该是存在的,但实际上并没有。null 常被用来清空一个变量,表明该变量应该指向一个对象,但现在没有指向任何对象。

二、数据类型的转化

当你看见这么一些语句时,思考一下它会输出什么?console.log([]==![]) console.log(+[]) console.log(1+[]);

(1)、原始值转原始值(显示类型转换)

1、转布尔Boolean

javascript
复制代码
let s = 's' let n = 123 let f = false let u = undefined let nu = null console.log(Boolean(s)); console.log(Boolean('')) console.log(Boolean(n)); console.log(Boolean(0)); console.log(Boolean(-1)); console.log(Boolean(Infinity)); console.log(Boolean(-Infinity)) console.log(Boolean(NaN)); console.log(Boolean(null)); console.log(Boolean(undefined)); console.log(Boolean(false)) console.log(Boolean());

为什么是这样的结果呢?其实在Js中原始值转化为布尔值遵循内定好的规则,它们决定了布尔上下文中(条件语句、逻辑运算符等)中如何解释这些值,比如我们有的时候会这么写

scss
复制代码
if(1){ ... ... } while(1){ ... ... }

这里if、while中的条件不是布尔时,编译器首先会根据下列规则,显示的将它们转化为布尔值。

  • 转Number数值
javascript
复制代码
console.log(Number('123')) console.log(Number('123adc')); console.log(Number('')) console.log(Number(true)); console.log(Number('0x03')); console.log(Number(null)); console.log(Number(undefined)); console.log(Number(Infinity)); console.log(Number(-Infinity)); console.log(Number());

undefined: 结果为NaN

null: 结果为0

String:

  • 全部为数字、以0开头的十六进制数:直接转化为对应的值
  • 特定字符串如"Infinity""-Infinity":直接输出
  • 带有字母(无法解析为数字):结果为NaN

Symbol:Symbol类型的值不能直接转换为Number,尝试这样做会抛出TypeError异常。(符号类型不适用于ToNumber操作)

BigInt: 直接将BigInt值转换为Number可能会导致精度损失或溢出。

Number: 直接返回本身

(2)、对象转原始值(隐式类型转换)

1、转Number数值

先调用ToNumber(x),该函数中会再调用ToPrimitive({},Number)将对象转化为原始值

ToPrimitive(obj,Nubmber)

  1. 判断接收到的值是不是原始类型,是则返回
  2. 否则,调用valueOf方法,如果得到了原始值,则返回
  3. 否则,调用toString()方法,如果得到了原始值,则返回
  4. 报错

2、转字符串: String({}) 先调用ToString(x),该函数中会再调用ToPrimitive()将对象转为原始值

ToPrimitive(obj,String)

  1. 判断接收到的值是不是原始类型,是则返回
  2. 否则,调用toString()方法,如果得到了原始值,则返回
  3. 否则,调用valueOf方法,如果得到了原始值,则返回
  4. 报错

注:调用一次ToPrimitive后还不是原始值,JavaScript引擎会进行第二次尝试,这次是调用第一个参数的toString()方法

3、转布尔 任何对象都是转布尔都是true

(三)、一元操作符与二元操作符、“==”vs“===”

1、一元操作符“+”

在数据类型转换中,使用一元操作符会往Number转

2、二元操作符“+”

在涉及字符串与其他类型(如数字、布尔值等)相加时。当+操作符的一边是字符串(或两边都是字符串),另一边是其他类型时,会进行字符串拼接。

vbscript
复制代码
console.log(5 + "apple"); // 输出 "5apple" console.log(3.14 + "pi"); // 输出 "3.14pi" console.log(NaN + "test"); // 输出 "NaNtest" console.log(true + "world"); // 输出 "1world" console.log(false + "example"); // 输出 "0example" console.log({}.toString() + " object"); // 通常输出 "[object Object] object",取决于对象的toString实现 console.log(null + "empty"); // 输出 "empty",因为null转为00与字符串拼接 console.log(undefined + "value"); // 输出 "undefinedvalue"

3、“==”会触发隐式类型转换,“===”则不会

当“==”两边数据类型不同时,会先进行隐式转换之后,在进行判断,而“===”为全等,要数据类型和值完全相等,也叫严格等于。

现在就可以来解决上面的问题[]==![] console.log(1+[]); console.log(+[])的输出结果了

1、首先!将[]转化为布尔类型true,然后进行取反,即[]==!true

然后false转数值为0,即[]==0

接着将[]转为数值,调用Number,在Number中又会调用ToPrimitive(obj,Nubmber 所以在中间的转换过程会有这一步''==0

最后,空字符串转数值为零,0==0,输出true

2、加号两边都有数据,所以为二元操作符,但是没有字符串类型的数据,转为数值直接相加,输出为1

3、加号只有一边有数据,为一元操作符,转为数值为0

三、数据类型判断

(一)、typeof()

javascript
复制代码
let str = 'hello' let num = 123 let flag = false let un = undefined let nu = null let obj = {} let arr = [] let fn = function(){} console.log(typeof str) console.log(typeof num) console.log(typeof flag) console.log(typeof un) console.log(typeof nu) console.log(typeof obj) console.log(typeof arr) console.log(typeof fn)

它可以判断除null以外的原始数据类型,不能判断除function的引用类型

  • typeof的判断原理是:将值转化为二进制后,看其前三位是不是0 除函数外,所有的引用类型的二进制前三位都是0,null的二进制全部是0

instanceof()

javascript
复制代码
let str = 'hello' let num = 123 let flag = false let un = undefined let nu = null let obj = {} let arr = [] let fn = function(){} let data =new Date() console.log(str instanceof String) //false console.log(num instanceof Number); //false console.log(flag instanceof Boolean); //false // console.log(un instanceof undefined); //error // console.log(nu instanceof null) //error console.log(obj instanceof Object); //true console.log(arr instanceof Array); //true console.log(fn instanceof Function) //true console.log(data instanceof Date) //true console.log(arr instanceof Object) //true

只能用于判断引用类型

  • 是通过原型链的查找来判断的

Object.prototype.toString()

数组的toString(): 将数组中的元素,用逗号隔开拼接成字符串

其他的toString(): 直接将值修改成字符串字面量

object的toString()

  • 如果toString接收的值是undefined,则返回"[object Undefined]".
  • 如果toString接收的值是null,则返回"[object Null]".
  • 调用ToObject(x)将x转为对象,此时得到的对象内部一定拥有一个属性[[class]],而属性[[class]]的值就是x的类型设class是[[class]]的值返回由"[object" 和class 和"]"拼接得到的字符串

数值以及其他都无法访问到Object上的toString方法,而是访问了Array、Number等自己内置的toString,这样就不能达到类型判断的目的,但是我们知道,Object的Prototype上toString可以做到这一点,所以用Object.prototype.toString()来判断它们的数据类型,这里我们call一下,就可以将它的this指向要判断的对象上 Object.prototype.toString.call([]) 【这里有对call以及this的介绍】一起走走this关键字走过的路——this的指向问题 - 掘金 (juejin.cn)

太干了,小编都要去喝水了,咱们下期再见!

对了,在Array上,自带了Array.isArray方法,可以用来判断是否是数组

源文:JS中的数据类型转换与判断,一篇带你全搞定

如有侵权请联系站点删除!

Technical cooperation service hotline, welcome to inquire!