Skip to content

类型检测

基础检测方法

typeof操作符

typeof操作符返回一个字符串,表示未经计算的操作数的类型

  • 底层是按照二进制的方式来检查其类型的,计算机用64位二进制数存储变量(000 对象,1 整数,010 浮点数,100,字符串,110 布尔,000000 null,-2^30 undefined)null为全0所以检测为对象类型,是一个历史遗留问题。
javascript
typeof value // 使用形式, 返回字符串 

typeof 42 // 'number'
typeof 'str' // 'stirng'
typeof true // 'booolean'
typeof undefined // 'undefined'
typeof Symbol() // 'symbol'
typeof BigInt(1) // 'bigint'
typeof null // 'object'

typeof {} // 'object'
typeof [] // 'object'
typeof function() {} // 'function'

instanceof

instanceof操作符用于检测构造函数的prototype属性是否出现在某个实例对象的原型链上

javascript
object instanceof constructor // 使用形式,返回布尔值

[] instanceof Array // true
new Date() instanceof Date // true

new Number(1) instanceof Number // true
Number(1) instanceof Number // false
1 instanceof Number // false


let Person = function() {}
let person = new Person()
person instanceof Person // true

instanceof的实现原理,顺着原型链去找,直到找到相同的原型对象,返回true,否则为false

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

进阶检测方法

Object原型检测

javascript
Object.prototype.toString.call(NaN) // '[object Number]'
Object.prototype.toString.call(undefined) // '[object Undefined]'
Object.prototype.toString.call([]) // '[object Array]'
Object.prototype.toString.call(null) // '[object Null]'
Object.prototype.toString.call({}) // '[object Object]'
Object.prototype.toString.call(document) // '[object HTMLDocument]'
Object.prototype.toString.call(window) // '[object Window]'


class Person {
    get [Symbol.toStringTag]() {
        return 'person'
    }
}
Object.prototype.toString.call(new Person()) // '[object Person]'

专门检测方法

javascript
Array.isArray([]) // true
Number.isNaN(NaN) // true
Number.isInteger(42) // true

特殊类型检测

null检测

javascript
const isNull = vlaue => value === null

NaN检测

javascript
const isNaN = vlaue => value !== NaN
Number.isNaN(NaN)

类数组检测

javascript
const isArrayLike = obj => {
    return obj !== null && typeof obj.length === 'number' && obj.length >= 0
}

综合检测方案

javascript
const getType = obj => {
   const type = Object.prototype.toString.call(obj)

   return type.slice(8, -1).toLowerCase()
}

getType(1) // number
getType([]) // array
getType(null) // null

检测方法对比

检测目标推荐方法注意事项
基本类型tyoeofnull返回'object'
NaNNumber.isNaN()、isNaN()能区分undefined
Number.isNaN()直接检查是否是NaN
isNaN()先尝试转为数字,若无法转为数字返回true,否则返回false(判断是否是数字)
数组类型Array.isArray()兼容IE9+
自定义对象instanceof跨框架失效
无法判断基本类型
null和undefined不是任何对象的实例,始终返回false
无法准确判断自定义类的的继承关系
可被手动原型链干扰
类数组对象检测length属性需要配合其他方式
精确类型判断Object.prototype.toString.call()返回[object Type]格式字符串

Released under the MIT License.