JavaScript数据类型判断方法typeof、instanceof、Object.prototype.toString

114 阅读3分钟

一、基础数据类型判断方法typeof 

typeof 操作法返回一个字符串

typeof 1 // 'number'
typeof '1' //'string'
typeof undefined // 'undefined'
typeof true // 'boolean'
typeof Symbol() //'symbol'
typeof null // 'object'
typeof [] // 'object'
typeof {} // 'object'
typeof console // 'object'
typeof console.log // 'function'

typeof 的局限性

typeof会返回一个变量的基本类型,可以判断基础数据类型(null除外),但是引用数据类型中,除了function类型以外,其他也无法判断。

typeof null; // "object"(错误)
typeof [];   // "object"(无法区分数组和对象)

二、复杂引用数据类型instanceof 

instanceof运算符用于检测构造函数的prototype属性是否出现在某一实例对象的原型链上,使用如下:

基础语法

object instanceof constructor

object为实例对象,constructor为构造函数

该操作符会返回布尔值,当objectconstructor的实例时,返回true,反之则返回false

function Vehicle() {}
function Car() {}
Car.prototype = new Vehicle(); // 手动设置继承关系

const myCar = new Car();
console.log(myCar instanceof Car); // true
console.log(myCar instanceof Vehicle); // true
// 定义构建函数
let Car = function() {}
let benz = new Car()
benz instanceof Car // true
let car = new String('xxx')
car instanceof String // true
let str = 'xxx'
str instanceof String // false

原理

function myInstanceof(left, right) {
    // 这里先用typeof来判断基础数据类型,如果是,直接返回false
    if(typeof left !== 'object' || left === null) return false;
    // getPrototypeOf是Object对象自带的API,能够拿到参数的原型对象
    let proto = Object.getPrototypeOf(left);
    while(true) {
        if(proto === null) return false;
        if(proto === right.prototype) return true;//找到相同原型对象,返回tru
e
        proto = Object.getPrototypeOf(proto);
    }
}

也就是顺着原型链去找,直到找到相同的原型对象,返回 true ,否则为 false

三、全局通用的数据类型判断方法 Object.prototype.toString

Object.prototype.toString 是 JavaScript 中用于检测数据类型的强大方法,比 typeof 和 instanceof 更可靠。

基本用法

通过 call/apply 调用该方法,可以返回一个格式为 [object 类型] 的字符串,其中 类型 表示对象的具体类型。

Object.prototype.toString.call(null) //"[object Null]"
Object.prototype.toString.call({}) //"[object object]"

检测各种数据类型

以下是常见数据类型的检测结果:

数据类型返回值
null[object Null]
undefined[object Undefined]
数组 [][object Array]
日期 new Date()[object Date]
正则 /.*/[object RegExp]
函数 function()[object Function]
数字 123[object Number]
字符串 'abc'[object String]
布尔值 true[object Boolean]
普通对象 {}[object Object]
DOM 元素[object HTMLDivElement](具体元素类型)
window[object Window]

实现类型判断函数

利用该方法可以封装一个通用的类型检测函数:

function getType(value) {
    let type = typeof value;
    if(type !== "object"){ //先进行typeof判断,如果是基础数据类型,直接返回true
        return type 
    }
    //对于typeof返回结果是object的,再进行如下判断,正则返回结果
    return Object.prototype.toString.call(value).replace(/^\[object (\S+)\]$/,'$1')
}

console.log(getType(null));        // "Null"
console.log(getType([1, 2]));      // "Array"
console.log(getType(new Map()));   // "Map"

与其他类型检测方法的对比

  1. typeof 的局限性

typeof会返回一个变量的基本类型,可以判断基础数据类型(null除外),但是引用数据类型中,除了function类型以外,其他也无法判断。

```
typeof null; // "object"(错误)
typeof [];   // "object"(无法区分数组和对象)
```

2. instanceof 的局限性

`instanceof`返回的是一个布尔值,可以准确判断复杂引用数据类型,但是不能正确判断基础数据类型

```
const arr = [];
arr instanceof Array; // true
arr instanceof Object; // true(无法精确区分)
```