前言
在开发过程中,这种需要判断数据类型的操作还是常见的,特别是一些公共组件里的数据处理方法,又或者对一些功能函数,比如递归深拷贝,需要对不同的数据做出判断.
在js中,数据分为基础类型和引用类型.比如字符串,数字等就属于基础类型,对象数组等属于引用类型.
共有五种方法,都是本人亲测.而这几种方法,有完美的,有不完美的,下面一一测试
数据准备
这里准备了很多类型或者同类型各种形式出现的数据
let argumentFun = function(a,b,c){
return arguments
}
class Myclass{
constructor(params) {
this.value = 1
}
}
let arr = [
'我是一个字符串', //字符串
9999, //number
true, //boolean
{name:'王惊涛'}, //存储对象
['1','2','3'], //数组
NaN, //NaN
null, //null
undefined, //安迪范的
new Object(), //object
Symbol(10), //symbol
BigInt(999999999), //bigInt
function(){console.log('普通函数')}, //普通函数
()=>{console.log('箭头函数')}, //箭头函数
argumentFun(), //类数组
Myclass, //类
window, //全局的window
new Date(), //时间类型,
Math, //Math
/^\w+$/ //正则
]
typeof方法
代码
console.log('typeof方法---------------')
typeofFun(arr)
function typeofFun(value){
arr.forEach(item=>{
console.log(item,':',typeof item)
})
}
结果
结论
typeof能有效区分基础类型的变量,但是对于引用类型和特殊一些的数据则无法区分,所以用来判断数组,布尔,字符串和安迪范的就好
instanceof方法
instanceof
运算符用于检测构造函数的 prototype
属性是否出现在某个实例对象的原型链上。(MDN上的原定义)
语法为 object instanceof constructor
即为 : (实例对象) instanceof (构造函数)
代码
let str1 = '1'
let str2 = new String('1')
let udfd1 = undefined
let udfd2 = new Object(undefined)
let nan1 = NaN
let nan2 = new Number(NaN)
let obj1 = {
name:'wjt'
}
let obj2 = new Object({
name:'wjt'
})
let arr1 = [1,2,3]
let arr2 = new Array(1,2,3)
let reg1 = /^\w+$/
let reg2 = new RegExp(/^\w+$/)
let fun1 = function(a,b){
return arguments
}
let fun2 = new Function((a,b)=>{
return arguments
})
/** instanceof方法测试 */
console.log(str1 instanceof String,'基础类型定义','str1') //false
console.log(str2 instanceof String,'包装类型定义','str2') //true
console.log(udfd1 instanceof Object,'基础类型定义','udfd1') //false
console.log(udfd2 instanceof Object,'包装类型定义','udfd2') //true
console.log(nan1 instanceof Number,'基础类型定义','nan1') //false
console.log(nan2 instanceof Number,'包装类型定义','nan2') //true
console.log(obj1 instanceof Object,'字面量定义','obj1') //true
console.log(obj2 instanceof Object,'new构造定义','obj2') //true
console.log(arr1 instanceof Array,'字面量定义','arr1')
console.log(arr2 instanceof Array,'new构造定义','arr2')
console.log(reg1 instanceof RegExp,'字面量定义','reg1') //true
console.log(reg2 instanceof RegExp,'new构造定义','reg2') //true
console.log(fun1 instanceof Function,'字面量定义','fun1') //true
console.log(fun2 instanceof Function,'new构造定义','fun2') //true
console.log(fun1() instanceof Object,'字面量定义','fun1()') //true
console.log(fun2() instanceof Object,'new构造定义','fun2()') //true
结果
扫描二维码关注公众号,回复:
16604926 查看本文章
结论
直接定义的基础类型不可以使用instanceof判断,引用类型或者包装之后的基础类型可以
constructor方法
代码
let str1 = '1'
let str2 = new String('1')
let udfd1 = undefined
let udfd2 = new Object(undefined)
let nan1 = NaN
let nan2 = new Number(NaN)
let obj1 = {
name:'wjt'
}
let obj2 = new Object({
name:'wjt'
})
let arr1 = [1,2,3]
let arr2 = new Array(1,2,3)
let reg1 = /^\w+$/
let reg2 = new RegExp(/^\w+$/)
let fun1 = function(a,b){
return arguments
}
let fun2 = new Function((a,b)=>{
return arguments
})
/** constructor方法 */
console.log(str1.constructor,'str1')
console.log(str2.constructor,'str2')
// console.log(udfd1.constructor,'udfd1') error
console.log(udfd2.constructor,'udfd2')
console.log(nan1.constructor,'nan1')
console.log(nan2.constructor,'nan2')
console.log(obj1.constructor,'obj1')
console.log(obj2.constructor,'obj2')
console.log(reg1.constructor,'obj1')
console.log(reg2.constructor,'obj2')
//下面的全为true
console.log(str1.constructor === String)
console.log(udfd2.constructor === Object)
console.log(nan1.constructor === Number)
console.log(obj1.constructor === Object)
console.log(reg1.constructor === RegExp)
console.log(arr1.constructor === Array)
console.log(fun1().constructor === Object)
// console.log(fun2().constructor,'========') error
结果
结论
可以查询数据的属性,但是特殊情况下会有报错
is类型的api
Object.prototype.toString.call方法
代码
let argumentFun = function(a,b,c){
return arguments
}
class Myclass{
constructor(params) {
this.value = 1
}
}
let arr = [
'我是一个字符串', //字符串
9999, //number
true, //boolean
{name:'王惊涛'}, //存储对象
['1','2','3'], //数组
NaN, //NaN
null, //null
undefined, //安迪范的
new Object(), //object
Symbol(10), //symbol
BigInt(999999999), //bigInt
function(){console.log('普通函数')}, //普通函数
()=>{console.log('箭头函数')}, //箭头函数
argumentFun(), //类数组
Myclass, //类
window, //全局的window
new Date(), //时间类型,
Math, //Math
/^\w+$/ //正则
]
/** toString.call()方法 */
tocall(arr)
function tocall(value){
arr.forEach(item=>{
//好几种写法,一个意思
// console.log(item,':',toString.call(item))
// console.log(item,':',Object.prototype.toString.call(item))
// console.log(item,':',Object.prototype.toString.apply(item))
console.log(item,':',Object.prototype.toString.bind(item)())
})
}
结果
结论
[object ???]的结果,各种类型都区分的很明白,最完美的一个方法.
并且语法好几个,都可以
总结
为了代码的安全和健壮,果断选最后一个吧.
Object.prototype.toString.call( ??? ) 或者 toString.call( ??? )