目录:
1.基本数据类型
2.引用数据类型
3.检测数据类型的方法
1.基本数据类型
• number
• string
• boolean
• null
• undefined
• symbol
这里讨论的不是通过new出来的基本类型,也就是说讨论的不是他们的包装类
因为当用包装类的方式时,用typeof判定都是object
2.引用数据类型
• Object ( Array 、 Date 、 RegExp )
• Function
3.检测数据类型的4种方式
3.1 typeof 讲解
3.1.1typeof的使用
返回值是字符串。例如undefined、object、boolean、symbol
我们先看下面的几个typeof的判断:
typeof null // object
typeof undefined // undefined
typeof 52 // number
typeof "laochen" // string
typeof true // boolean
typeof Symbol() // symbol
typeof (()=>{}) //function
typeof {} // object
typeof [] // objcet
typeof /aaaa/ //objcet
typeof new Date() //objcet
总结:typeof 无法判断具体对象类型,如时间,正则,数组,空对象,null 都为objcet
3.1 .2typeof的原理
js是一门弱类型语言,每个变量在存储值之外,还会存储变量的类型,js中使用32位的bit存储变量信息,低位的1-3个bit存储变量类型信息,我们可以叫它为类型标签type tag。
举个例子:
...... xxxxx x000 //最后三位,000为objcet
...... xxxxx x001 //最后一位,为1时则是int
...... xxxxx x010 //倒数第二位则为 double
...... xxxxx x100 //倒数三位,则为string
...... xxxxx x110//倒数第三位和第二位为1,则为boolean
所以,null undefined 和Function 并没有分配type tag
那么,typeof能通过一个对象是否实现了[[call]] 内部方法,如果实现了,则判断为Function,而undfined 变量 存储的是一个特殊的值,typeof会判断这个值,则认为是undefined
null是个特殊的例子,因为存储的低位恰好也是000,跟object是一致的,命中type tag,所以通过typeof是无法判断null的。
如何判断一个对象不是null
比较经典的解法:
可以通过objcet装修的功能
function getObjcet(obj){
return Objcet(obj) === obj;
}
getObjcet({}) //true
getObject(null) // false
3.2 Objcet.prototype.toString 可以用来判断各种内置对象
3.2.1 Objcet.prototype.toString 解释
如果是一个实参的基本类型,会自动转化成为对应的引用类型。
null和undefined不存在对应的引用类型,会转为内部特殊处理。
3.2.2 Objcet.prototype.toStrting 的原理
每个对象都有一个内部属性 [[Class]],它的值有 'Argunments' 'Array' 'Boolean' 'Date' 'Error' 'Function' 'JSON' 'Math' 'Number' 'Objcet' 'RegExp' 'String' ,并且只能通过Objcet.prototype.toString来访问
3.2.3 Symbol.toStringTag 被访问
其实Objcet.prototype.toString内部会先访问对象的Symbol.toStringTag属性值来拼接返回值。
我们可以验证一下
let aa = 'test'
console.log(Objcet.prototype.toString.call(aa)) // "[object String]"
Objcet.defineProperty(String.prototype,Symbol.toStringTag,{
get(){
return 'ibeatyou'
}
})
console.log(Object.prototype.toString.call(test)) // [object ibeatyou]
前后对比,就可以知道,先访问Symbol.toStringTag,返回了 get()的值。
3.2.4 Object.prototype.toString 的使用总结
- 如果是undefined ,返回[object Undefined]
- null => [object Null]
- 如果是基本类型或者是内置对象,则转化为封装类型[object 封装类型]
- 获取对象的Symbol.toStringTag 属性值subType 如果subType是个字符串,则返回[object subType] 否则,就会获取对象的[[Class]] 属性值 type ,返回[object type]
3.3 instanceof
3.3.1 instanceof的原理及语法
instanceof 操作符判断构造函数constructorFunc的prototype属性是否存在对象object的原型链上。同时我们可以利用Symbol.hasInstance函数自定义intanceof操作逻辑。
Object.create({}) instanceof Object // true
Object.create(null) instanceof Object // false 此方法可以判断数据是否为null的对象
Function instanceof Object // true
Object instanceof Object // true
Symbol.hasInstance自定义instanceof:
let obj = {}
Object.defineProperty(obj,Symbol.hasInstance,{
value:function(){
return true;
}
})
52 intanceof obj // true
3.3.2 instanceof的总结
1)instanceof 不会对基本类型做隐式转换。
如:'1111' instanceof String // false
2)constructorFunc必须是一个对象,并且大部分情况下是个构造函数。具有prototype属性。
52 instanceof 52 // 错误不是对象
1 instanceof {} // 错误
({}) instanceof (()=>{}) // Function 没有prototype属性
3)instanceof 的缺陷,因为不同的全局执行上下文的对象和函数都是不相等的,所以对于跨全局执行上下文instanceof 就不能正常工作了。
3.4 内置的类型判断方法
3.4.1 Array.isArray
Es5引入了用于数组类型的判断方法
3.5 内置对象的prototype属性类型判断
基本类型的引用类型.prototype
- 该写法不是该引用类型的实例。
- 通过 Object.prototype.toString.call() 可以判断他的类型
// 举例
let num = Number.protype
console.log(num instanceof Number) // false
console.log(Object.prototype.toString.call(num)) // [object Number]