|
在javascript中,typeof 和 instanceof 是用來(lái)判斷數(shù)據(jù)類(lèi)型比較通用的兩個(gè)方法,這篇文章的目的是通過(guò)對(duì)這兩個(gè)方法介紹來(lái)分析其存在的不足并提出優(yōu)化方案。
typeof typeof 返回一個(gè)表達(dá)式的數(shù)據(jù)類(lèi)型的字符串,返回結(jié)果為javascript中的基本數(shù)據(jù)類(lèi)型,包括:number、boolean、string、object、undefined、function等6種數(shù)據(jù)類(lèi)型。 typeof 100; //number typeof (1==1); //boolean typeof 'onepixel'; //string typeof {} ; //object typeof onepixel; // undefined typeof parseInt; // function typeof [];//object typeof new Date(); //object 可以看出,typeof 可以準(zhǔn)確的判斷除object以外的基礎(chǔ)數(shù)據(jù)類(lèi)型,但不能區(qū)分object類(lèi)型的具體類(lèi)型,比如 Array 、Date 以及自定義類(lèi)。
instanceof instanceof 本意是用來(lái)判斷 A 是否為 B 的實(shí)例對(duì)象,表達(dá)式為:A instanceof B,如果A是B的實(shí)例,則返回true,否則返回false。 在這里需要特別注意的是:instanceof檢測(cè)的是原型,那它是怎么檢測(cè)的呢,我們用一段偽代碼來(lái)模擬其內(nèi)部執(zhí)行過(guò)程: instanceof (A,B) = { var L = A.__proto__; var R = B.prototype; if(L === R) { //A的內(nèi)部屬性__proto__指向B的原型對(duì)象 return true; } return false; } 從上述過(guò)程可以看出,當(dāng)A的__proto__ 指向B的prototype時(shí),就認(rèn)為A就是B的實(shí)例對(duì)象,我們?cè)賮?lái)看幾個(gè)例子: [] instanceof Array; //true {} instanceof Object;//true new Date() instanceof Date;//true function Person(){}; new Person() instanceof Person; [] instanceof Object; //true new Date() instanceof Object;//tru new Person instanceof Object;//true 從上面的例子中,我們發(fā)現(xiàn)雖然instanceof能夠正確判斷[] 是Array的實(shí)例對(duì)象,但不能辨別 [] 不是Object的實(shí)例對(duì)象,為什么呢,這還需要從javascript的原型鏈說(shuō)起,我們首先來(lái)分析一下[]、Array、Object 三者之間的關(guān)系,從instanceof判斷能夠得出:[].__proto__ ->Array.prototype, 而Array.prototype.__proto__指向了Object.prototype,Object.prototype.__proto__ 指向了null,標(biāo)志著原型鏈的結(jié)束。(ps:關(guān)于JS原型鏈請(qǐng)閱讀:淺談javascript原型和原型鏈) 因此,[]、Array、Object就形成了一條原型鏈:
從原型鏈可以看出,[]的__proto__最終指向了Object.prototype,類(lèi)似的new Date()、new Person() 也會(huì)形成這樣一條原型鏈,因此,我們用 instanceof 也不能完全精確的判斷object類(lèi)的具體數(shù)據(jù)類(lèi)型。
優(yōu)化方案 對(duì)于這個(gè)問(wèn)題,在閱讀jQuery源碼時(shí),發(fā)現(xiàn)了一個(gè)比較好的解決方案,由于源碼之間存在相互調(diào)用不便于閱讀和理解,因此,按照其思路進(jìn)行了整理和封裝,代碼如下: (function(){ var class2type = {}; var typeList = "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ); typeList.eachEach(function(item){ class2type[ "[object " + item + "]" ] = item.toLowerCase(); } return { getObjType:function(obj) { if ( obj == null ) { return obj + ""; } if(typeof obj === "object" || typeof obj === "function"){ class2type[ toString.call( obj ) ] || "object" }else { return typeof obj; } } } })() 代碼僅供參考,如有不同見(jiàn)解,歡迎交流!
by @ 一像素 2016.01 歡迎轉(zhuǎn)載和分享,但請(qǐng)注明出處和鏈接!
|
|
|
來(lái)自: 昵稱10504424 > 《工作》