在強類型語言,數組類型檢測是非常容易的事情(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]" } function isObject(value) { return value instanceof Object } //對於通過字面量定義的對象和new Object的對象返回true,new Object時傳參數的返回false //new Object時傳參數的構造函數的原型鏈沒有isPrototypeOf屬性,而構造函數的原型鏈的__proto__對象有。 function isPlainObject(value) { var key, ctor //如果不是object類型返回。 if (toString.call(value) !== "[object Object]") return false //獲得該對象原型鏈中的屬性或者對象 ctor = (isFunction(value.constructor) && value.constructor.prototype) //該原型鏈中沒有對象或者屬性 或者有但是不屬性不存在isPrototypeOf,返回為false if (!ctor || !hasOwnProperty.call(ctor, 'isPrototypeOf')) return false for (key in value); return key === undefined || hasOwnProperty.call(value, key) } function isArray(value) { return value instanceof Array } function likeArray(obj) { //類數組,不是真正的數組,是對象,有一個成員類型“length” return typeof obj.length == 'number' }