判断数据类型
Contents
总结
Object.prototype.toString.call(obj)
最准确。- typeof 只能检测基本数据类型。
利用
typeof
来判断number
,string
,object
,boolean
,function
,undefined
,symbol
这七种类型null会判断为’object’,引用类型除了函数外其他都会被判断为’object'
- instanceOf 只能检测引用数据类型
总结
适用于 | 返回 | |
---|---|---|
typeof | 基本数据类型 | string |
instanceof | 引用数据 | true/false |
Object.prototype.toString |
都可以 | string |
Object.prototype.toString.call(obj)
原理
返回 obj 所属类的信息。
- 基本类型数据原型上的toString方法都是把当前的数据类型转换为字符串的类型(它们的作用仅仅是用来转换为字符串的)
- 引用类型数据上的toString返回当前方法执行的主体(方法中的this)所属类的信息即
[object Object]
=。
Object.prototype.toString.call('') ; // [object String]
Object.prototype.toString.call(1) ; // [object Number]
Object.prototype.toString.call(true) ; // [object Boolean]
Object.prototype.toString.call(undefined) ; // [object Undefined]
Object.prototype.toString.call(null) ; // [object Null]
Object.prototype.toString.call(new Function()) ; // [object Function]
Object.prototype.toString.call(new Date()) ; // [object Date]
Object.prototype.toString.call([]) ; // [object Array]
Object.prototype.toString.call(new RegExp()) ; // [object RegExp]
Object.prototype.toString.call(new Error()) ; // [object Error]
Object.prototype.toString.call(document) ; // [object HTMLDocument]
Object.prototype.toString.call(window) ; //[object global] window是全局对象global的引用
检验方法
Object.prototype.toString.call(a).split(' ')[1].slice(0,-1).toLowerCase()
typeof
原理
基于js底层存储变量数据类型的值(二进制)进行检测
类型 | typeof 结果 | |
---|---|---|
基本类型 | undefined | “undefined” |
Boolean | “boolean” | |
Number | “number” | |
String | “string” | |
BigInt (ECMAScript 2020 新增) | “bigint” | |
Symbol | “symbol” | |
null | “object” | |
引用类型 | Object(Object、Array、Map、Set等) | “object” |
Function | “function” |
对于原始类型来说,除了 null 都可以调用 typeof 显示正确的类型。null会被检测为object,是js底层的一个bug。
语法
typeof检测null是一个对象
typeof检测函数返回时一个function
typeof检测其他对象都返回 object
typeof 1 // 'number'
typeof '1' // 'string'
typeof undefined // 'undefined'
typeof true // 'boolean'
typeof Symbol() // 'symbol'
typeof console.log // 'function'
但对于引用数据类型,除了函数之外,都会显示"object"。
typeof [] // 'object'
typeof {} // 'object'
typeof null; //object
instanceof
原理
判断当前类出现在实例的原型链上。
表达式为:A instanceof B,如果A是B的实例,则返回true,否则返回false。
语法
[] instanceof Array; //true
{} instanceof Object;//true
new Date() instanceof Date;//true
new RegExp() instanceof RegExp//true
const Person = function() {}
const p1 = new Person()
p1 instanceof Person // true
const str1 = 'hello world'
str1 instanceof String // false
const str2 = new String('hello world')
str2 instanceof String // true
弊端
-
不能检测null 和 undefined
const arr = [1, 2, 3]; console.log(arr instanceof null)//Uncaught TypeError: Right-hand side of 'instanceof' is not an object console.log(arr instanceof undefined)//Uncaught TypeError: Right-hand side of 'instanceof' is not an object
对于特殊的数据类型null和undefined,他们的所属类是Null和Undefined,但是浏览器把这两个类保护起来了,不允许我们在外面访问使用。
- 对于基本数据类型来说,字面量方式创建出来的结果和实例方式创建的是有一定的区别的,所以不能检测基本类型数据。
console.log(1 instanceof Number)//false
console.log(new Number(1) instanceof Number)//true
- 只要在当前实例的原型链上,我们用其检测出来的结果都是true。在类的原型继承中,我们最后检测出来的结果未必准确。
const arr = [1, 2, 3];
console.log(arr instanceof Array) // true
console.log(arr instanceof Object); // true
function fn(){}
console.log(fn instanceof Function)// true
console.log(fn instanceof Object)// true
源码实现
// 实例.__proto__===类.prototype
function instance_of(example, classFunc) {
let classFuncPrototype = classFunc.prototype
let proto = Object.getPrototypeOf(example)
while (true) {
if (proto === null) {
return false
}
if (proto === classFuncPrototype) {
return true
}
proto = Object.getPrototypeOf(proto)
}
}
console.log(instance_of({}, Array))//false