01. 类型判断
(1)typeof操作符
-
一般的,我们可以通过
typeof操作符来简单的判断一个变量的数据类型 -
typeof操作符会返回这些字符串:number、string、boolean、symbol、bigint、undefined、object、function
-
特别的:
typeof可以判断除了 null 以外的原始类型,typeof null == object(这是因为null表示的是一个空对象指针)typeof只能判断引用类型中的Function,其他的引用类型判断出来都为object
typeof 12 // number
typeof 'Ruovan' // string
typeof false // boolean
typeof Symbol() // symbol
typeof 123n // bigint
typeof undefined // undefined
typeof {} // object
typeof null // object
typeof function(){} // function
因此,
typeof最适合用来判断原始类型的变量,对于引用类型作用不大
(2)instanceof操作符
-
instanceof操作符可以用来判断引用类型的变量的具体类型,其返回值是true | false- 对于原始类型的变量始终返回
false,因此不适用于原始类型的判断
- 对于原始类型的变量始终返回
-
instanceof主要是通过原型链的方式来判断数据类型的(原型链这里不展开讲)-
它会检测构造函数的原型对象
prototype是否出现在某个实例对象的原型链上 -
或者说检测实例对象A是否是构造函数B的实例对象
-
或者说检测
B的原型对象B.prototye是否存在于A的原型链上 -
拓展:
- 类似的,在
Object上也存在一个方法也可以用来检测一个对象是否存在于另一个对象的原型链上 Object.prototype.isPrototypeOf()
// 用于检查 B.prototype 是否在 A 的原型链上 B.prototype.isPrototypeOf(A) // => A instanceof B - 类似的,在
# A instanceof B [] instanceof Array // true {} instanceof Object // true function(){} instnaceof Function // true // 当然,Function、Array也都是引用类型,所以 [] instanceof Object // true function(){} instanceof Object // true // 对于原始类型 'Ruovan' instanceof String // false 24 instanceof Number // false ... -
因此,对于引用类型,通常可以使用
instanceof来进行判断,不过它也不是那么准确,数组、方法都可能被判断为Object另外,数组有自己的方法来判断一个变量是否是数组:
Array.isArray(),返回值为true | false
(3)Object.prototype.toString方法
-
toString()方法会返回一个表示该对象类型的字符串- 可以通过
call改变this指向,可以将this指向要检测的值(因为该方法有可能被重写)
- 可以通过
-
这应该是最准确的判断,能判断所有类型,并得到一个类似
[object Type]的字符串// [object Type] ———— 注意,Type首字母是大写 # Object.prototype.toString.call(...) Object.prototype.toString.call(24) // [object Number] Object.prototype.toString.call('Ruovan') // [object String] Object.prototype.toString.call({}) // [object Object] Object.prototype.toString.call([]) // [object Array]
-
拓展:
- 可以看到,这个方法输出的结果可能并不是我们想要的,所以进行一下二次封装,并结合一下之前的
typeof操作符
// getType 方法 const getType = function(obj) { let type = typeof obj // 对于原始类型,typeof 就可以判断了,对于结果为 object 的,再使用 toString()来进行 if (type !== 'object') { return type } // 因为 toString() 方法返回的是一个字符串,所以我们要对字符串进行处理,以得到我们想要的 类型部分 // 正则处理,记得转为小写—— toLowerCase() return Object.prototype.toString.call(obj).replace(/^[object (\S+)]$/, '$1').toLowerCase() // slice:因为前面的都是一样的 [object Type] return Object.prototype.toString.call(obj).slice(8,-1).toLowerCase() // split:或者用空格分开再 slice return Object.prototype.toString.call(obj).split(' ')[1].slice(0,-1).toLowerCase() } - 可以看到,这个方法输出的结果可能并不是我们想要的,所以进行一下二次封装,并结合一下之前的
本人前端小菜鸡,如有不对请谅解