您的位置:首页 > Web前端 > JavaScript

JS数据类型检测

2016-04-04 04:29 791 查看
在强类型语言,数组类型检测是非常容易的事情(typeof就可以解决),而在弱语言JS数据类型就很容易混淆了。

JS中常见的数据类型有:number、string、boolean、undefined、function、array、Object和null。下面先用typeof来测试下:

var k = 9;
console.log(typeof k);  //number


检测number可以用typeof来检测了。

var k = "string";
console.log(typeof k);  //string


检测string可以用typeof来检测了。

var k = true;
console.log(typeof k);   //Boolean


检测boolean可以用typeof来检测了。

var u;
console.log(typeof u);  //undefined


检测undefined也可以用typeof来检测。

var f = function(){};
console.log(typeof f);   //function


function 也可以用typeof来检测。

var t = null;
console.log(typeof t);   //object
var array = [];
console.log(typeof array); //object
var obj = {};
console.log(typeof obj);    //object


用typeof来检测null,array和object检测的都是object。看来需要对这三种数据结构进行特殊处理。

function type(o){
return (o === null) ? "null": (typeof o)
}


先对null进行特殊处理,在看看array和object有没有其它属性来判断。

var array = [];
var toString = Object.prototype.toString;
console.log(toString.apply(array)); //[object Array]

var obj = {};
console.log(toString.apply(obj));//[object Object]


OK,通过检测其它数据类型:regexp和date也可以通过这种方式来检测:

var regex = /^\s+/;
var toString = Object.prototype.toString;
console.log(toString.apply(regex));  //[object RegExp]
var date = new Date();
console.log(toString.apply(date));  //[object Date]


最后,我们来写一个通用的函数来对JS数据类型检测:

function typeOf(e){
var _toString = Object.prototype.toString;
var _type = {
"undefined":"undefined",
"number":"number",
"boolean":"boolean",
"string":"string",
"function":"function",
"[object RegExp]":"regex",
"[object Array]":"array",
"[object Date]":"date"
}
return _type[typeof  e] || _type[_toString.call(e)] ||(e? "object":"null");
}


我在zepto.js中看到另外一些检测数据类型的方式,可以参考:

var toString = ({}).toString; //挺巧妙的。
function isFunction(value) {
return toString.call(value) == "[object Function]"
}
// value通过对象字面量定义的对象,或者通过new定义的对象isObject(value)都为true
function isObject(value) {
return value instanceof Object
}
//对于通过字面量定义的对象,new定义的实例对象为false
//new Object时传参数的构造函数的原型链没有isPrototypeOf属性,而构造函数的原型链的__proto__对象有。
function isPlainObject(value) {
var key, ctor
//如果不是object类型返回false。
if (toString.call(value) !== "[object Object]") return false
//获得该对象原型链中的属性或者对象,如果是对象自面量,那么isFunction(value.constructor)为false,是构造函数定义则为true,不管是false,还是true
//value.constructor.prototype都返回对象,即ctor为一个对象,并且该对象没有isPrototypeOf属性!
ctor = (isFunction(value.constructor) && value.constructor.prototype)   //true
//解释一下:isPrototypeOf:如果对象 A 存在于 对象obj的原形链中,则 A.isPrototypeOf(obj)返回true,而obj必定继承了A 的属性
//!ctor为false,查看ctor是否有'isPrototypeof'属性值,都不会存在isPrototypeOf属性
if (!ctor || !hasOwnProperty.call(ctor, 'isPrototypeOf')) return false
//如果value为{},那么执行for (key in value)之后,key为最后一个元素,如果是通过Object.create来创建的,则key为undefined。
//如果是构造函数构造的对象,key为原型链中的方法,即hasOwnProperty.call(value, key)为false,
for (key in value);
//那么就可以确定{}返回为false,函数或者其他都返回为true;
return key === undefined || hasOwnProperty.call(value, key);
}
function isArray(value) {
return value instanceof Array
}
function likeArray(obj) {     //类数组,不是真正的数组,是对象,有一个成员类型“length”
return typeof obj.length == 'number'
}


来看看一个特殊的例子:

console.log({}?"x":"y"); //"x"
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: