---
url: https://sugarat.top/bigWeb/js/p4.md
---

# 判断数据类型的方案

## 判断变量类型的方案

### 1. typeof

* 对于原始值类型除了null外都可以准确判断
* 对于对象来说，除了函数都会显示 object
  * `null`不是对象
    :::tip 原始值类型
* number
* string
* boolean
* symbol
* undefined
* null `不能使用typeof正确判断`
  :::

### 2. instanceof

* 通过原型链进行判断

```js
[] instanceof Array // true
{} instanceof Object // true
new String('sss') instanceof String // true
```

* 通过instanceof判断string值类型的方法
  * Symbol.hasInstance能够让我们自定义函数的行为

```js
class myString{
    static [Symbol.hasInstance](str){
        return typeof str === 'string'
    }
}
'ss' instanceof myString // true
```

### 3. String.prototype.toString

> Object.prototype.toString方法返回对象的类型字符串，因此可以用来判断一个值的类型

不同对象都定义了自己的toString方法

不同数据类型的Object.prototype.toString方法返回值如下：

* 数值：返回\[object Number]。
* 字符串：返回\[object String]。
* 布尔值：返回\[object Boolean]。
* undefined：返回\[object Undefined]。
* null：返回\[object Null]。
* 数组：返回\[object Array]。
* arguments 对象：返回\[object Arguments]。
* 函数：返回\[object Function]。
* Error 对象：返回\[object Error]。
* Date 对象：返回\[object Date]。
* RegExp 对象：返回\[object RegExp]。
* 其他对象：返回\[object Object]。

所以可以通过`.call`方法改变`this`的指向以达到判断的目的

```js
Object.prototype.toString.call(2) // "[object Number]"
Object.prototype.toString.call('') // "[object String]"
Object.prototype.toString.call(true) // "[object Boolean]"
Object.prototype.toString.call(undefined) // "[object Undefined]"
Object.prototype.toString.call(null) // "[object Null]"
Object.prototype.toString.call(Math) // "[object Math]"
Object.prototype.toString.call({}) // "[object Object]"
Object.prototype.toString.call([]) // "[object Array]"
```

## 书写一个通用的

```js
function type (o){
  var s = Object.prototype.toString.call(o);
  return s.match(/\[object (.*?)\]/)[1].toLowerCase();
};

type({}); // "object"
type([]); // "array"
type(5); // "number"
type(null); // "null"
type(); // "undefined"
type(/abcd/); // "regex"
type(new Date()); // "date"
```
