js中的数据分为基本数据类型和引用数据类型,引用数据类型中也有数组、对象、函数的区分,在工作中,有时我们需要对传入参数的值类型做判断。
在js中,有非常多的方法来判断数据类型,但是各个用法也大不相同,这次我们来汇总下这些方法。
typeof
先上代码:
typeof 'seymoe' // 'string'
typeof true // 'boolean'
typeof 10 // 'number'
typeof Symbol() // 'symbol'
typeof null // 'object' 无法判定是否为 null
typeof undefined // 'undefined'
typeof {} // 'object'
typeof [] // 'object'
typeof(() => {}) // 'function'
typeof只对boolean、number、string、function四种类型是有效的,范围非常窄,对应的我们要慎用typeof这种方法。
instanceof
instanceof是用来判断是否是构造函数的实例,是通过原型链来判断的,instanceof检测的是原型,举个栗子:
// 简单原理
instanceof (A,B) = {
var L = A.__proto__;
var R = B.prototype;
if(L === R) {
// A的内部属性 __proto__ 指向 B 的原型对象
return true;
}
return false;
}
// 例子
[] instanceof Array; // true
{} instanceof Object;// true
new Date() instanceof Date;// true
function Person(){};
new Person() instanceof Person; // true
[] instanceof Object; // true
// 最后都指向了Object.prototype
new Date() instanceof Object;// true
new Person instanceof Object;// true
const str = "abc"
const str2 = new String("abc")
str instanceof String // false
str2 instanceof String // true
construct
其实和instanceof差不多,都是通过原型来判断,略过不讲。
Object.prototype.toString()
先来看各个类型的返回值:
Object.prototype.toString.call({}) // '[object Object]'
Object.prototype.toString.call([]) // '[object Array]'
Object.prototype.toString.call(() => {}) // '[object Function]'
Object.prototype.toString.call('str') // '[object String]'
Object.prototype.toString.call(1) // '[object Number]'
Object.prototype.toString.call(true) // '[object Boolean]'
Object.prototype.toString.call(Symbol()) // '[object Symbol]'
Object.prototype.toString.call(null) // '[object Null]'
Object.prototype.toString.call(undefined) // '[object Undefined]'
Object.prototype.toString.call(new Date()) // '[object Date]'
Object.prototype.toString.call(Math) // '[object Math]'
Object.prototype.toString.call(new Set()) // '[object Set]'
Object.prototype.toString.call(new WeakSet()) // '[object WeakSet]'
Object.prototype.toString.call(new Map()) // '[object Map]'
Object.prototype.toString.call(new WeakMap()) // '[object WeakMap]'
高级程序设计3上有这样一句话:在任何值上调用 Object 原生的 toString() 方法,都会返回一个 object NativeConstructorName 格式的字符串。每个类在内部都有一个[[Class]] 属性,这个属性中就指定了上述字符串中的构造函数名。
我们做个小封装:
function myTypeOf(obj) {
return toString.call(obj).slice(8, -1).toLowerCase()
}
myTypeOf(1) // 'number'
myTypeOf("str") // 'string'
myTypeOf([]) // 'array'
Array.isArray()
判断是否是数组
Array.isArray([1,2]) // true
Array.isArray(1) // false
Array.isArray({}) // false