你真的了解js的类型检测吗?

154 阅读1分钟

typeof

  • 在计算机底层基于数据类型的值(二进制)进行检测
  • typeof null  "object"  对象存储在计算机中,都是以000开始的二进制存储,null 也是,所以检测出来的结果是object
  • typeof  普通对象/数组对象/正则对象/日期对象  都是"object"

例:

typeof  1  // "number"
typeof NaN // "number"
typeof undefined // "undefined"
typeof "add" // "string"
typeof true // "boolean"
typeof null // "object"
typeof  []  // "object"
typeof {} // "object"
typeof function() {} // "function"

typeof 1111n // "bigInt"

instanceof   检测当前实例是否是这个类

  • 底层机制:只要当前类出现在实例的原型上,结果为true
  • 由于我们可以修改原型的指向检测出来的结果是不准确的
  • 不能基本数据类型

例:

let arr = []
console.log(arr instanceof Array) // true
console.log(arr instanceof RegExg) // false
console.log(arr instanceof Object) // true

function fn(){
    this.x = 100
}
fn.prototype = Array.__proto__
let f = new fn
console.log(f instanceof Array)  // true

console.log(1 instanceof Number) // fasles

手写instanceof

// 实例.__proto__ === 类.prototype
function instance_of (example, classFunc) {
    let classFuncPrototype = classFunc.prototype
    // let proto = example.__proto__  IE浏览器不兼容
    let proto = Object.getPrototype(example)
    while(true) {
        if(proto === null) {
           // Object.prototype.__proto__ === null
           return false
        }
        if(proto === classFuncPrototype){
            return true
        }        
        proto = Object.getPrototype(proto)
    }
}

let arr = []
console.log(instance_of(arr, Array))
console.log(instance_of(arr, RegExg))
console.log(instance_of(arr, Object))

constructor

  • 支持基本类型
  • constructor 可以随便改,所以结果也是不准确的

例:

let arr = []
console.log(arr.constructor === Array) // true
console.log(arr.constructor === RegExp) // false
console.log(arr.constructor === Object) // false

let n = 1
console.log(n.constructor === Number) // true

Number.prototype.custructor = "AA"
console.log(n.constructor === "Number"  // false 

Object.prototepy.toString.call([value])

  • 标准检测数据类型的方法,返回的是当前实例所属类的信息

例:

let obj = {
 name: '2222'
}

obj.toString()   // "[object Object]"
toString方法执行,this是obj,所以检测的是obj它的所属类信息

Object.prototype.toString.call(1) // "[object Number]"
Object.prototype.toString.call(NaN) // "[object Number]"
Object.prototype.toString.call("") // "[object String]"
Object.prototype.toString.call(true) // "[object Boolean]"
Object.prototype.toString.call(null) // "[object Null]"
Object.prototype.toString.call(undefined) // "[object Undefined]"
Object.prototype.toString.call(function(){}) // "[object Function]"
Object.prototype.toString.call([]) // "[object Array]"
Object.prototype.toString.call({}) // "[object Object]"
Object.prototype.toString.call(/^$/) // "[object RegExp]"
Object.prototype.toString.call(new Date()) // "[object Date]"