Javascript類型判斷相關(guān)例題及解析
題目:
請(qǐng)?jiān)趇ndex.html文件中,編寫arraysSimilar函數(shù),實(shí)現(xiàn)判斷傳入的兩個(gè)數(shù)組是否相似。具體需求:
1. 數(shù)組中的成員類型相同,順序可以不同。例如[1, true] 與 [false, 2]是相似的。
2. 數(shù)組的長(zhǎng)度一致。
3. 類型的判斷范圍,需要區(qū)分:String, Boolean, Number, undefined, null, 函數(shù),日期, window.
當(dāng)以上全部滿足,則返回"判定結(jié)果:通過",否則返回"判定結(jié)果:不通過"。
一、測(cè)試用例
var result=function(){ //以下為多組測(cè)試數(shù)據(jù) var cases=[{ arr1:[1,true,null], arr2:[null,false,100], expect:true },{ arr1:[function(){},100], arr2:[100,{}], expect:false },{ arr1:[null,999], arr2:[{},444], expect:false },{ arr1:[window,1,true,new Date(),"hahaha",(function(){}),undefined], arr2:[undefined,(function(){}),"okokok",new Date(),false,2,window], expect:true },{ arr1:[new Date()], arr2:[{}], expect:false },{ arr1:[window], arr2:[{}], expect:false },{ arr1:[undefined,1], arr2:[null,2], expect:false },{ arr1:[new Object,new Object,new Object], arr2:[{},{},null], expect:false },{ arr1:null, arr2:null, expect:false },{ arr1:[], arr2:undefined, expect:false },{ arr1:"abc", arr2:"cba", expect:false }]; //使用for循環(huán), 通過arraysSimilar函數(shù)驗(yàn)證以上數(shù)據(jù)是否相似,如相似顯示“通過”,否則"不通過",所以大家要完成arraysSimilar函數(shù),具體要求,詳見任務(wù)要求。 for(var i=0;i<cases.length;i++){ if(arraysSimilar(cases[i].arr1,cases[i].arr2)!==cases[i].expect) { document.write("不通過!case"+(i+1)+"不正確!arr1="+JSON.stringify(cases[i].arr1)+", arr2="+JSON.stringify(cases[i].arr2)+" 的判斷結(jié)果不是"+cases[i].expect); return false; } } return true; }(); document.write("判定結(jié)果:"+(result?"通過":"不通過"));
這個(gè)文件為testData.js。主要任務(wù)是完成arraysSimilar函數(shù)。
二、arraySimilar函數(shù)
1、我的寫法
1、判斷2個(gè)參數(shù)是否都是數(shù)組,不是就返回false;
2、判斷2個(gè)數(shù)組長(zhǎng)度是否一致,不是直接返回fasle;
3、新建2個(gè)臨時(shí)數(shù)組temp1,temp2并初始化為0,用來存放arr1和arr2中各種類型的個(gè)數(shù)。
var temp1 = [0, 0, 0, 0, 0, 0, 0, 0];
var temp2 = [0, 0, 0, 0, 0, 0, 0, 0];
4、遍歷2個(gè)arr1和arr2,每遍歷一個(gè)元素,將對(duì)應(yīng)類型加1。
5、完成arr1和arr2的遍歷后,通過temp1.toString()和temp2.toString()是否相等得出2個(gè)數(shù)組是否相似。
<!DOCTYPE HTML> <html> <meta charset="utf-8"> <head> <meta http-equiv="Content-Type" content="text/html; charset=gb18030"> <title>Untitled Document</title> </head> <body> <script type="text/javascript"> /* * param1 Array * param2 Array * return true or false */ function arraysSimilar(arr1, arr2) { console.log("arr1為" + arr1); console.log("arr2為" + arr2); if (!(arr1 instanceof Array) || !(arr2 instanceof Array)) { document.write(false + "<br/>"); return false; } else if (arr1.length != arr2.length) { document.write(false + "<br/>"); return false; } var temp1 = [0, 0, 0, 0, 0, 0, 0, 0]; var temp2 = [0, 0, 0, 0, 0, 0, 0, 0]; //初始化temp1 for (i = 0; i < arr1.length; i++) { console.log("arr1的第" + i + "個(gè)值為" + arr1[i]); switch (jsType(arr1[i])) { case "String": temp1[0]++; break; case "Boolean": temp1[1]++; break; case "Number": temp1[2]++; break; case "Undefined": temp1[3]++; break; case "Null": temp1[4]++; break; case "Function": temp1[5]++; break; case "Date": temp1[6]++; break; case "Window": temp1[7]++; break; } console.log("arr2的第" + i + "個(gè)值為" + arr2[i]); //初始化temp2 switch (jsType(arr2[i])) { case "String": temp2[0]++; break; case "Boolean": temp2[1]++; break; case "Number": temp2[2]++; break; case "Undefined": temp2[3]++; break; case "Null": temp2[4]++; break; case "Function": temp2[5]++; break; case "Date": temp2[6]++; break; case "Window": temp2[7]++; break; } } //判斷temp1和temp2是否相等 if (temp1.toString() === temp2.toString()) { document.write(true + "<br/>"); return true; } else { document.write(false + "<br/>"); return false; } } //返回參數(shù)的javascript類型 function jsType(arg) { //判斷字符串 if (typeof arg == "string") { console.log("string"); return "String"; } //判斷Boolean if (typeof arg == "boolean") { console.log("boolean"); return "Boolean"; } //判斷Number if (typeof arg == "number") { console.log("Number"); return "Number"; } //判斷Undefined if (typeof arg == "undefined") { console.log("Undefined"); return "Undefined"; } //判斷Null(不考慮IE8以下) //看了答案發(fā)現(xiàn)直接=== null判斷就好了 if (Object.prototype.toString.apply(arg) == "[object Null]") { console.log("Null"); return "Null"; } //判斷Function if (typeof arg == "function") { console.log("Function"); return "Function"; } //判斷日期 if (arg instanceof Date) { console.log("Date"); return "Date"; } //判斷window //看了答案發(fā)現(xiàn)直接=== window 判斷就好了 if (arg instanceof Window) { console.log("window"); return "Window"; } } </script> <script src="testData.js"></script> </body> </html>
雖然代碼略粗糙,但是功能完成了。網(wǎng)上看了其他人的答案確實(shí)不同的人做法不一樣,有些值得借鑒的地方。
2、其他答案
建一個(gè)類型對(duì)象數(shù)組obj,初始化為零,arr1遍歷時(shí)每個(gè)元素對(duì)應(yīng)的類型加一,arr2遍歷時(shí)每個(gè)元素對(duì)應(yīng)的類型減一,最終判斷obj里所有鍵的值都為0即相似數(shù)組。
function check(i){ //除了function 其他的引用類型用instanceof來判定 if(i instanceof Date){ return 'date'; } else if(i instanceof Window){ return 'window'; } // typeof可以判斷基本類型(number string boolean null(typeof 返回object) undefined )和引用類型的function類型 if(typeof i === 'number')return 'number'; else if(typeof i === 'string')return 'string'; else if(typeof i === 'boolean')return 'boolean'; else if(typeof i === 'function')return 'function'; //typeof null 返回 object else if(typeof i === 'object'){ if(i === null){ return 'null'; }else{ return 'object'; } } else if(typeof i === 'undefined'){ return 'undefined'; } } function arraysSimilar(arr1, arr2){ if(!arr1||!arr2){return false;} if(!(arr1 instanceof Array )||!(arr2 instanceof Array))return false; if(arr1.length!=arr2.length)return false; var obj={ 'number':0, 'string':0, 'boolean':0, 'undefined':0, 'null':0, 'function':0, 'date':0, 'object':0, 'window':0 }; for(var i=0;i<arr1.length;i++){ var r1=check(arr1[i]); var r2=check(arr2[i]); obj[r1]++; obj[r2]--; } for(var o in obj){ if(obj[o]!=0)return false; } return true; }
還有一個(gè)答案,差不多算標(biāo)準(zhǔn)答案,當(dāng)然這種題也沒有標(biāo)準(zhǔn)答案。和上個(gè)答案的差別是,用map(在js中也就是對(duì)象)存放數(shù)據(jù)類型和次數(shù),這個(gè)map初始化為{},在后面動(dòng)態(tài)生成的。
/** * String, Boolean, Number, undefined, null, 函數(shù),日期, window */ function arraysSimilar(arr1, arr2) { // 判斷參數(shù),確保arr1, arr2是數(shù)組,若不是直接返回false if (!(arr1 instanceof Array) || !(arr2 instanceof Array)) { return false; } // 判斷長(zhǎng)度 if (arr1.length !== arr2.length) return false; var i = 0, n = arr1.length, countMap1 = {}, // 用來計(jì)算數(shù)組元素?cái)?shù)據(jù)類型個(gè)數(shù)的map,key是TYPES中的類型字符串,value是數(shù)字表示出現(xiàn)次數(shù)。 countMap2 = {}, t1, t2, TYPES = ['string', 'boolean', 'number', 'undefined', 'null', 'function', 'date', 'window']; // 因?yàn)槭菬o(wú)序的,用一個(gè)對(duì)象來存儲(chǔ)處理過程。key為類型, value為該類型出現(xiàn)的次數(shù)。 // 最后校驗(yàn):若每一種數(shù)據(jù)類型出現(xiàn)的次數(shù)都相同(或都不存在),則證明同構(gòu)。 for (; i < n; i++) { t1 = typeOf(arr1[i]); t2 = typeOf(arr2[i]); if (countMap1[t1]) { countMap1[t1]++; } else { countMap1[t1] = 1; } if (countMap2[t2]) { countMap2[t2]++; } else { countMap2[t2] = 1; } } // 因?yàn)閠ypeof只能判斷原始類型,且無(wú)法判斷null(返回"object"),所以自己寫typeof方法擴(kuò)展。 function typeOf(ele) { var r; if (ele === null) r = 'null'; // 判斷null else if (ele instanceof Array) r = 'array'; // 判斷數(shù)組對(duì)象 else if (ele === window) r = 'window'; // 判斷window else if (ele instanceof Date) r = 'date' // 判斷Date對(duì)象 else r = typeof ele; // 其它的,使用typeof判斷 return r; } for (i = 0, n = TYPES.length; i < n; i++) { if (countMap1[TYPES[i]] !== countMap2[TYPES[i]]) { return false; } } return true; }
還有一個(gè)比較簡(jiǎn)潔也好理解的解法
<script type="text/javascript"> /* * param1 Array * param2 Array * return true or false */ function type(a){ return a === null ? '[object Null]':Object.prototype.toString.apply(a); //hack ie678 } function arraysSimilar(arr1, arr2){ if(!Array.isArray(arr1) || !Array.isArray(arr2) ||arr1.length!=arr2.length){return false;} var arr3=[]; var arr4=[]; var x; for(var i in arr1){ arr3.push(type(arr1[i])); arr4.push(type(arr2[i])); } if(arr3.sort().toString()==arr4.sort().toString()){ return true; }else{ return false; } } </script>
還有一個(gè)精妙的解法,我對(duì)這種不感興趣,沒仔細(xì)看。
var global = window; function arraysSimilar(arr1, arr2){ return (arr1 instanceof Array && arr2 instanceof Array) && JSON.stringify(arr1.map(function(v) { return null === v ? "☀" : (v instanceof Date ? "❤" : (v === global ? "❀" : typeof v)); }).sort()) === JSON.stringify(arr2.map(function(v) { return null === v ? "☀" : (v instanceof Date ? "❤" : (v === global ? "❀" : typeof v)); }).sort()); }
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
讓你的博文自動(dòng)帶上縮址的實(shí)現(xiàn)代碼,方便發(fā)到微博客上
添加以下代碼到你的博客中: (呵呵,抄襲至lulu Studio http://s8.hk/0itw)2010-12-12JS實(shí)現(xiàn)可自定義大小,可雙擊關(guān)閉的彈出層效果
這篇文章主要介紹了JS實(shí)現(xiàn)可自定義大小,可雙擊關(guān)閉的彈出層效果,涉及JavaScript定時(shí)函數(shù)及頁(yè)面元素動(dòng)態(tài)操作的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-10-10Bootstrap企業(yè)網(wǎng)站實(shí)戰(zhàn)項(xiàng)目4
這篇文章主要為大家分享了Bootstrap企業(yè)網(wǎng)站實(shí)戰(zhàn)項(xiàng)目,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-10-10javascript:文字不間斷向左移動(dòng)的實(shí)例代碼
這篇文章介紹了javascript:文字不間斷向左移動(dòng)的實(shí)例代碼,有需要的朋友可以參考一下2013-08-08B/S開發(fā)中常用javaScript技術(shù)與代碼
B/S開發(fā)中常用javaScript技術(shù)與代碼...2007-03-03微信小程序使用toast消息對(duì)話框提示用戶忘記輸入用戶名或密碼功能【附源碼下載】
這篇文章主要介紹了微信小程序使用toast消息對(duì)話框提示用戶忘記輸入用戶名或密碼功能,結(jié)合實(shí)例形式詳細(xì)分析了toast組件實(shí)現(xiàn)消息提示功能的相關(guān)操作技巧,并附帶源碼供讀者下載參考,需要的朋友可以參考下2017-12-12js簡(jiǎn)單的點(diǎn)擊返回頂部效果實(shí)現(xiàn)方法
這篇文章主要介紹了js簡(jiǎn)單的點(diǎn)擊返回頂部效果實(shí)現(xiàn)方法,實(shí)例分析了實(shí)現(xiàn)返回頂部效果的相關(guān)要點(diǎn)與實(shí)現(xiàn)技巧,需要的朋友可以參考下2015-04-04JavaScript實(shí)現(xiàn)滑塊補(bǔ)圖驗(yàn)證碼效果
這篇文章主要給大家介紹了JavaScript如何實(shí)現(xiàn)滑塊補(bǔ)圖驗(yàn)證碼效果,文章通過代碼示例介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴可以參考閱讀下2023-07-07webpack中的filename 和 chunkFilename 的區(qū)別實(shí)例解析
filename 指列在 entry 中,打包后輸出的文件的名稱,chunkFilename 指未列在 entry 中,卻又需要被打包出來的文件的名稱,這篇文章主要介紹了webpack中的filename 和 chunkFilename 的區(qū)別實(shí)例解析,需要的朋友可以參考下2023-11-11