一行代码实现数据类型判断
JS 判断数据类型,方法有很多,如 typeof、constructor、toString 等等,甚至可以使用 jQuery 内部的 $.type 都可以判断。其中 typeof 等的判断局限性都比较大,如 typeof 只能判断数据存储类型,constructor 只能判断数据的原型,toString 相对比较完整一点,但显示不够友好,在 jQuery 中对其做了一些修饰,正是Object.prototype.toString
的功劳。
Object.prototype.toString.call(1)
// "[object Number]"
Object.prototype.toString.call('1')
// "[object String]"
Object.prototype.toString.call({})
// "[object Object]"
Object.prototype.toString.call([])
// "[object Array]"
Object.prototype.toString.call(window)
// "[object global]"
注意到了吗?每个数据类型的返回值都有一个相同点,那就是[object
,通过取值后面的文字可以获取到该对象的数据类型。即:
Object.prototype.toString.call(object).slice(8, -1).toLowerCase();
Object.prototype.toString.call(1).slice(8, -1).toLowerCase();
// "number"
Object.prototype.toString.call('1').slice(8, -1).toLowerCase();
// "string"
Object.prototype.toString.call({}).slice(8, -1).toLowerCase();
// "object"
Object.prototype.toString.call([]).slice(8, -1).toLowerCase();
// "array"
Object.prototype.toString.call(window).slice(8, -1).toLowerCase();
// "global"
初始的typeis
就是这样的:
/**
* 判断数据类型
* @param obj {*} 任何数据
* @returns {string}
*/
var typeis = function (obj) {
return Object.prototype.toString.call(obj).slice(8, -1).toLowerCase();
};
通过测试可知:
typeis(NaN);
// "number"
不太符合预期,需要额外判断一次
/**
* 判断数据类型
* @param obj {*} 任何数据
* @returns {string}
*/
var typeis = function (obj) {
var ret = Object.prototype.toString.call(obj).slice(8, -1).toLowerCase();
if(isNaN(obj) && ret === 'number'){
return 'nan';
}
return ret;
};
判断 element 元素的时候:
typeis(document.body)
// "htmlbodyelement"
typeis(document.head)
// "htmlheadelement"
不符合预期,再修改:
/**
* 判断数据类型
* @param obj {*} 任何数据
* @returns {string}
*/
var typeis = function (obj) {
var ret = Object.prototype.toString.call(obj).slice(8, -1).toLowerCase();
if (isNaN(obj) && ret === 'number') {
return 'nan';
} else if (/element/.test(ret)) {
return 'element';
}
return ret;
};
最后再对一些全局对象,做些处理:
/**
* 判断数据类型
* @param obj {*} 任何数据
* @returns {string}
*/
var typeis = function (obj) {
var udf = 'undefined';
if (typeof obj === udf) {
return udf;
} else if (typeof window !== udf && obj === window) {
return 'window';
} else if (typeof global !== udf && obj === global) {
return 'global';
} else if (typeof document !== udf && obj === document) {
return 'document';
} else if (obj === null) {
return 'null';
}
var ret = Object.prototype.toString.call(obj).slice(8, -1).toLowerCase();
if (isNaN(obj) && ret === 'number') {
return 'nan';
} else if (/element/.test(ret)) {
return 'element';
}
return ret;
};
一个比较完善、完整的 typeis 就出来了。
</>