一.typeof判断类型
1.直接在计算机底层基于数据类型的值(二进制)进行检测
2.typeof null "object" 对象存储在计算机中,都是以000开始的二进制存储,null也是,所以检测出来的结果是对象
3.typeof 普通对象/数组对象/正则对象/日期对象 检测都是“object”
console.log(typeof 1) // number
console.log(typeof '1') // string
console.log(typeof true) // boolean
console.log(typeof undefined) // undefined
console.log(typeof null) // object
console.log(typeof Symbol(1)) // symbol
console.log(typeof 11111n) // bigint
console.log(typeof function(){}) // function
console.log(typeof new Date()) // object
console.log(typeof /^$/) // object
console.log(typeof {}) // object
console.log(typeof []) // object
二. instanceof判断类型
`instanceof`** **运算符**用于检测构造函数的 `prototype` 属性是否出现在某个实例对象的原型链上。
1.底层机制:只要当前类出现在实例的原型链,结果都是true
2.由于我们可以肆意的修改原型的指向,所以检测出来的结果不准确
3.不能检测基本数据类型
let arr = []
console.log(arr instanceof Array) // true
console.log(arr instanceof Object) // true arr最顶层是object
console.log(arr instanceof RegExp) // false
// 缺点是arr的原型对象可以随时更改
arr.__proto__ = RegExp.prototype
console.log(arr instanceof Array) // false
console.log(arr instanceof Object) // true
console.log(arr instanceof RegExp) // true
手写一下instanceof可能更容易看懂🤔
function instance_of(example,classFunc){
// proto 拿到第一位参数的__proto__ classFuncProto拿到数据类型实例的prototype
// Object.getPrototypeOf(example)相当于 example.__proto__
let proto = Object.getPrototypeOf(example),
classFuncProto = classFunc.prototype
// 循环对比example原型链上否出现在这个实例原型对象
while(true){
// 原型比较相同返回
if(classFuncProto === proto) {
return true
}
// proto到最顶层时,返回false
if(proto === null) {
return false
}
proto = Object.getPrototypeOf(proto)
}
}
三.constructor判断类型
1.用起来看似比instanceof好用一些(基本类型支持)
2.选用的是当前prototype的constructor,
3.constructor属性可以随便改,所以也不准
let arr = []
let n =1
console.log(arr.constructor === Array) // true
console.log(arr.constructor === Object) // false
console.log(arr.constructor === RegExp) // false
console.log(n.constructor === Number) // Number
// 缺点
Array.prototype.constructor = '11'
console.log(arr.constructor === Array) // false
四.Object.prototype.toString.call()
1.标准的类型数据检测方法:Object.prototype.toString是返回当前势力所属类的信息
2.检测方法:"[object Number/String/Boolean/Null/undefined/Function/Symbol/Object/Array/Date/RegExp]"
console.log(Object.prototype.toString.call([])) // '[object Array]'
console.log(Object.prototype.toString.call({})) // '[object Object]'
console.log(Object.prototype.toString.call(function(){})) // '[object Function]'
...
五.提供一个自定义检测数据类型方法
正常情况下Object.prototype.toString.call()可以满足所有的数据类型判断,但在考虑到简单类型判断使用typeof更加轻便,认为jquery中的判断封装更为巧妙
(function () {
var classType = {}
var toString = classType.toString; // 相当于 Object.prototype.toString
// 设置数据类型的映射表
['Boolean', 'Number', 'String', 'Function', 'Array', 'Date',
'RegExp', 'Object', 'Error', 'Symbol'].forEach(name => {
classType[`[object ${name}]`] = name.toLowerCase()
})
var toType = function (obj) {
// null或者undefined不再做判断直接返回
if (obj == null) {
return obj + ''
}
// 复杂类型时在classType映射表中直接获取类型,简单类型走typeof判断
return typeof obj === "function" || typeof obj === "object" ?
classType[toString.call(obj)] : typeof obj
}
// toType绑定在全局中方便调用
window.toType = toType
})()
第一次写博客分享,肯定有很多不足之处,欢迎各位大佬指点0~0。