如果我们每天都用的数据类型不会判断的话 ,那和看见女神不想知道她名字有什么区别,看到数据类型不会转换的话,那和不想和女神在一起的咸鱼有什么区别。那么今天这篇文章,我将和你一起,从认识女神到和她在一起的方法,帮你全部搞定。
一、数据类型的种类
在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(){}
...
注: 其中undefined
和null
是比较难分清楚的,当你的钱包里没有钱的时候,那就是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)
- 判断接收到的值是不是原始类型,是则返回
- 否则,调用
valueOf
方法,如果得到了原始值,则返回 - 否则,调用
toString()
方法,如果得到了原始值,则返回 - 报错
2、转字符串:
String({})
先调用ToString(x),该函数中会再调用ToPrimitive()
将对象转为原始值
ToPrimitive(obj,String)
- 判断接收到的值是不是原始类型,是则返回
- 否则,调用
toString()
方法,如果得到了原始值,则返回 - 否则,调用
valueOf
方法,如果得到了原始值,则返回 - 报错
注:调用一次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转为0,0与字符串拼接 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
方法,可以用来判断是否是数组
如有侵权请联系站点删除!
技术合作服务热线,欢迎来电咨询!