JS之不得不会的数据类型判断

82 阅读1分钟

第一种:typeof

typeof返回被判断数据的类型的字符串

一些特殊例子如下

typeof null        //'object'
typeof [1,2,3]     //'object'
typeof new Date()  //'object'

精确区分普通对象和数组,请使用 Array.isArray() 或者 Object.prototype.toString.call()

如果使用 new 操作符来创建数据,会出现什么结果呢

let str = new String('String')
let num = new Number(100)
typeof str    //'object'
typeof num    //'object'

这是因为,除了 Function 构造函数之外,其他的构造函数的类型都是 'object'

由此可见,typeof 不能判断 null 和数组,而且由于 let 和 const 的出现,使得 typeof 可能会报引用错误

第二种:instanceof

instanceof用于检测构造函数的 prototype 属性是否出现于在左边对象的原型链中

一个简陋的实现 instanceof

function _instanceof(left, right){
    if(typeof left!== 'object' || left===null)return
    if(typeof right !== 'function')return
    let proto=Object.getPrototypeOf(left)
    let prototype=right.prototype
    while(true){
        if(proto===null){return false}
        if(proto===prototype){return true}
        proto=Object.getPrototypeOf(proto)
    }
}

注意,instanceof 不能判断 null 和 undefined,因为对它们使用 Object.getPrototypeOf 会直接报错,下面是一些特殊情况

let str='hello'
let string=new String('hi')

str instanceof String     //false
str instanceof Object     //false
string instanceof String  //true

这是因为 str 只是一个 string 类型的值,但它并不是 String对象的实例,同样,它也不是一个 Object对象的实例。

但是你会发现 Object.getPrototypeOf(str)=== String.prototype

第三种 Object.prototype.toString()

数组,数字,函数都覆盖了 toString 方法,我们想要判断数据类型,必须使用 Object 原型对象上的 toString,这就是在使用时需要使用 call 来调用的原因

如果你直接调用,即使你传了参数,也会被忽略,此时 toString 内部的 this 是 Object.prototype,结果永远都是 '[object Object]'

Object.prototype.toString(1)
'[object Object]'