Javascript数据类型说明及类型判断
Javascript数据类型
JavaScript 有 8 种类型的值呢,如果再归归类,我们还可以把它们分为两大类,分别是 原始类型(Primitive Type)和 对象类型(Object Type)。其中,原始数据类型包含了数字、布尔、字符串、BigInt、null、undefined,以及后来新增的 symbol,这个数据类型的值都是不可变的(immutable)。对象数据类型则包含我们经常说的对象,对象的值是可变的(mutable)。它是一个大类,如果再细分,它又包含了我们常用的 数组(array)、函数(function)、Date、RegExp,以及后来新增的 Map 和 Set。没错,我们经常用的数组、函数作为值都属于对象数据类型。

平常都比较注意引用类型带来的问题,但是比较忽略原始类型带来的痛楚,比如社区比较火爆的 0.1 + 0.2 === 03 不成立问题,这是因为精度丢失导致的。
JavaScript 的数字有两种类型分别是 整数 和 浮点数,而这个问题是浮点数之间的运算,浮点数可以很大也可以很小,位数越多占用的存储空间就越多,解决办法就是使用 科学计数法。JavaScript 所采用的 IEEE 754 是 二进制 浮点数算术标准。这个标准里规定了 4 种浮点数算术方式:单精确度、双精确度、延伸单精确度与延伸双精确度。JavaScript 在这里选择的又是 双精确度(64 位)这种方式,通常也叫 double 或者 float64 类型。把十进制转化为二进制的算法是用十进制的小数乘以 2 直到没有了小数为止,所以十进制下的有些小数无法被精确地表示成二进制小数。而既然这里的浮点数是二进制,因此小数就会存在 精度丢失 的问题。
而且当我们使用加减法的时候,由于需要先对齐(也就是把指数对齐,过程中产生移位),再计算,所以这个精度会进一步丢失。并且根据 JavaScript 引擎实际返回的小数点后的位数,可能会出现第三次丢失。这样下来,最后的结果就和实际相加减的数有偏离。
所以一般开发的时候都是把小数先放大倍数,做完运算后再缩小。
再比如虽然布尔类型的数据只有 true 和 false 两种,但是在 JavaScript 中除了 false 以外,undefined、null、0、NAN 和 ” 都是假值。
再比如 null 实际是一个空的对象指针
….
接下来,来好好理一理开发的时候应该怎么去判断 JavaScript 的各种数据类型
类型判断
typeof
typeof 是 一元操作符,放在单个操作数的前面,操作数可以是任意类型。返回值为表示操作数类型的一个字符串。
用 typeof 检测 JavaScript 中所有的数据类型会得到如下的结果
| 操作 | 结果 |
|---|---|
| typeof ‘string’ | ‘string’ |
| typeof 1 | ‘number’ |
| typeof true | ‘boolean’ |
| typeof undefined | ‘undefined’ |
| typeof Symbol() | ‘symbol’ |
| typeof null | ‘object’ |
| typeof {} | ‘object’ |
| typeof function test() {} | ‘function’ |
| typeof [] | ‘object’ |
| typeof new Map() | ‘object’ |
| typeof new Set() | ‘object’ |
| typeof new Date() | ‘object’ |
| typeof new Error() | ‘object’ |
可以看到,除开 typeof null === 'object' 是个 bug 不考虑以外,只有函数类型的对象能检测出来是个函数,也没有办法具体检测是个什么类型的函数,很多种正常类型的对象是没有办法检测出来具体的对象类型,咋办呢?Object.prototype.toString 是神器
Object.prototype.toString
早期写代码经常会搜类型判断,最常见的就是 Object.prototype.toString ,来看看对所有类型进行 toString 后是什么结果,ES5 规范 其实也写的很清楚了,我再翻译一下:
- 如果 this 值是 undefined,就返回 [object Undefined]
- 如果 this 的值是 null,就返回 [object Null]
- 让 O 成为 ToObject(this) 的结果
- 让 class 成为 O 的内部属性 [[Class]] 的值
- 最后返回由 “[object **” 和 class 和 “]**” 三个部分组成的字符串
通过规范,我们至少知道了调用 Object.prototype.toString 会返回一个由 “[object **” 和 **class 和 “]” 组成的字符串,而 class 是要判断的对象的内部属性。
用 Object.prototype.toString(表格中简写为toString)检测 JavaScript 中大部分常见的数据类型会得到如下的结果
| 操作 | 结果 |
|---|---|
| toString ‘string’ | [object String] |
| toString 1 | [object Number] |
| toString true | [object Boolean] |
| toString undefined | [object Undefined] |
| toString null | [object Null] |
| toString {} | [object Object] |
| toString [] | [object Array] |
| toString new Date() | [object Date] |
| toString new Error() | [object Error] |
| toString /a/g | [object RegExp] |
| toString function test() {} | [object Function] |
| toString Math | [object Math] |
| toString JSON | [object JSON] |
| Object.prototype.toString.call(new Map()) | [object Map] |
| Object.prototype.toString.call(new Set()) | [object Set] |
| Object.prototype.toString.call(Symbol()) | [object Symbol] |
| function test() {console.log(Object.prototype.toString(arguments))} | [object Arguments] |
| …… | …… |
1、部分文章来源于网络,仅作为参考。 2、如果网站中图片和文字侵犯了您的版权,请联系1943759704@qq.com处理!



