JavaScript 数据类型与类型判断

前言

JS 中的数据经常打交道,与之相关的数据类型,在平常开发中却不是很在意,只有在开发中遇到问题才会去搜索相关知识,而本身没有相关的知识储备。

上周面试中,面试官问了几个问题,慢慢意识到自己基础并不扎实。

Q1: JS 有哪些数据类型? A: number,boolean,string,null,undefined,symbol, object

Q2: 有哪些方法判断数据类型? A: typeof, instanceof

Q3: 还有别的方法? A: ??? 还有嘛(疑问: Array.isArray 对,这个方法可以判断数组,那还有别的方法可以判断别的数据类型嘛?)

Q4: 哪些是原始类型? A: number,boolean,string,undefined,symbolobject 不是原始类型。(疑问:那 null 呢? typeof null 也是 object, 函数呢,Date呢,正则呢, 那怎么判断某个类型是不是原始类型?)

同时,最后面试官举了个数据类型的使用场景,在写组件的时候,写公共函数的时候,需要去校验参数的类型,如果参数不对,需要抛出对应的错误。

的确,健壮性足够强的代码,应该要考虑到很多的情况,而这些的基础都要明确数据类型。

1. 数据类型

解决 Q1, 即以下八种数据类型,其中对象类型又包含函数对象,日期对象等

MDN 中已经说明了,JS 中有 8 种数据类型(七种原始类型和对象类型):

解决 Q4, 即以下七种类型是原始类型,其他对象类型都不是原始类型

七种原始类型: 1. number 2. string 3. boolean 4. null 5. undefined 6. bigint 7. symbol

原始类型存储的都是值,是没有属性或者方法的。 如 1.toString() 会报错,因为 1 这个基础类型没有 toString 方法。

注意: '1'.toString() 是可以的, 是因为在调用 toString 方法的时候,字符串 '1' 已经转为 字符串对象 了,而对象是有方法的。

对象类型: 除了原始类型,都是对象类型

  1. 标准对象,键值对 {}

  2. 函数对象

  3. 日期,Date 对象

  4. 数组,Array 对象

  5. 正则, RegExp 对象

  6. 错误,Error 对象

2. 数据类型

typeof 表达式

结果

typeof 1

number

typeof '1'

string

typeof true

boolean

typeof undefined

undefined

typeof function() {}

function

typeof Symbol('a')

symbol

typeof null

object

typeof {}

object

typeof new Date()

object

typeof /1/

object

typeof []

object

typeof new Error()

object

也就是说,typeof 可以检验出, number,string,boolean,undefined,function, symbol 类型,而对于 null 和 其他的对象类型数据,返回值都是 object,不能区分。

那如何区分, null, 标准对象,函数对象,日期对象,数组对象,错误对象和正则对象呢?

解决 Q2,Q3, 即还可以使用 Object.prototype.toString() 方法来判断类型

答案是 Object.prototype.toString()

Object.prototype.toString.call()

结果

Object.prototype.toString.call(1)

[object Number]

Object.prototype.toString.call('1')

[object String]

Object.prototype.toString.call(true)

[object Boolean]

Object.prototype.toString.call(undefined)

[object Undefined]

Object.prototype.toString.call(function() {})

[object Function]

Object.prototype.toString.call(Symbol(1))

[object Symbol]

Object.prototype.toString.call(null)

[object Null]

Object.prototype.toString.call({})

[object Object]

Object.prototype.toString.call(new Date())

[object Date]

Object.prototype.toString.call(/1/)

[object RegExp]

Object.prototype.toString.call([])

[object Array]

Object.prototype.toString.call(new Error())

[object Error]

接下来写一个 type 函数,该函数返回任意数据的数据类型。

至此,我们能判断原始类型以及一些对象类型。

3. 额外的 Utils 方法

3.1 isWindow

依据: window 对象有 window 属性指向自身。

3.2 isEmptyObject

依据: 空对象上没有属性

3.3 isElement

依据: DOM 元素的 nodeType 为 1

3.4 isValidDate (是否为有效的日期对象)

依据: isNaN(new Date('foo')) === true

此外,我们可以再关注一下 Date 的一下奇怪行为:

4. 数据类型与内存

在 JS 中,每一个数据都需要一个内存空间,而内存空间又被分为: 栈内存(stack)与堆内存(heap)。

number, boolean, string, null, undefined, symbol 这几种基础类型和函数,它们的值会存放在栈内存中。

而引用类型数据,如 Array (所需内存大小不一样), 标准对象 {}, 它们的值存放在堆内存中。

参考资料

Last updated

Was this helpful?