这个问题之前也没有想过,前不久有人问到这个问题,则回去了解了一下。首先给一个实例图:
表达式 | 值 |
ypeof true | ‘boolean’ |
typeof 56 | number |
typeof “567” | string |
typeof function(){} | ‘function’ |
typeof [1,2,3] | ‘object’ |
typeof {name:‘张三’,age:22} | ‘object’ |
typeof null | ‘object’ |
typeof undefined | ‘undefined’ |
typeof unknownVariable | ‘undefined’ |
由上诉表格可见,对于布尔值 数字 字符串以及函数这几种简单类型typeof是可以正确判断的,但是对于其他类型则可能会出现不可预期的错误。
解决办法:
判断Array :Array.isArray(arr) 准确判断一个数据类型是否为Array返回值为Boolean。
//infoVar 是需要判断类型的数据。
判断null:infoVar === null
判断某个全局变量是否存在: typeof window.infoVar ===‘undefined’。
函数内部判断某个变量是否存在用typeof infoVar=== ‘undefined’。
但通过以上解决方法,没有办法判断 typeof infoVar=== ‘undefined’的时候具体是定义还是未定义
于是可以封装成一个函数:
function isDefined(va) {
//var va;
//var va = null;
//var va = 'xxxx';
try{
// 已经声明
// 判断是否已经定义
if (va === undefined){
// 不能使用 ==,因为当 "var va = null;"时 被判定为未定义是错误的。
//if (typeof va === 'undefined'){ // 这种方式也是不可取的。
// 未定义
console.log("变量未定义.");
}else {
// 已经定义了,可能为null
console.log("变量已定义.");
}
} catch(e){
// va 未声明
console.log("变量未声明,");
}
}
对于判断具体数组或是对象的判断则还有以下方法:
1.instanceof
数组也是对象的一种,使用instanceof都会返回true
console.log(arr instanceof Array); //true
console.log(arr instanceof Object); //true
console.log(obj instanceof Array); //false
console.log(obj instanceof Object); //true
判断原理: instanceof 运算符用来测试一个对象在其原型链中是否存在一个构造函数的 prototype 属性,意思就是该变量通过原型链上能否找到构造函数的prototype 属性。
Array.prototype === arr.__proto__
Object.prototype === arr.__proto__.__proto__
2.constructor
console.log(arr.constructor === Array); //true
console.log(arr.constructor === Object); //false
console.log(obj.constructor === Object); //true
3.Object.prototype.toString.call()
Object.prototype.toString.call()方法可以精准判断变量类型,它返回[object constructorName]的字符串格式,constructorName是call参数的函数名
console.log(Object.prototype.toString.call([1,2,3])); //[object Array]
console.log(Object.prototype.toString.call({name:'张三',age:22})); //[object Object]
console.log(Object.prototype.toString.call(123)); //[object Number]
console.log(Object.prototype.toString.call(NaN)); //[object Number]
console.log(Object.prototype.toString.call("123")); //[object String]
console.log(Object.prototype.toString.call(null)); //[object Null]
console.log(Object.prototype.toString.call(false)); //[object Boolean]
console.log( Object.prototype.toString.call(undefined)); //[object Undefined]
console.log( Object.prototype.toString.call(Symbol())); //[object Symbol]
由于Object.prototype.toString.call()返回的不只是数据类型名称 所以可以简单的函数处理:
封装简单工具函数判断类型:
**
* 判断一个变量哪种类型
* @param {*} obj - 待判断变量
* @returns {string} 类型名称
*/
export function typeOf(obj) {
return toString.call(obj).slice(8, -1).toLowerCase()
}
总结
对于简单数据类型可以用typeof 判断 而对于数组对象以及其余复杂相对类型则需要用到其他方法 而Object.prototype.toString.call() 是更加精准的,所以建议使用。
声明
本篇内容根据两位博主博客@Yucihent,@BenjaminShih整合而得,仅作为一个学习笔记保留。