javascript类型判断

简介:

题目:

请在index.html文件中,编写arraysSimilar函数,实现判断传入的两个数组是否相似。具体需求:

1. 数组中的成员类型相同,顺序可以不同。例如[1, true] 与 [false, 2]是相似的。

2. 数组的长度一致。

3. 类型的判断范围,需要区分:String, Boolean, Number, undefined, null, 函数,日期, window.

当以上全部满足,则返回"判定结果:通过",否则返回"判定结果:不通过"。

一、测试用例

复制代码

var result=function(){    //以下为多组测试数据
            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循环, 通过arraysSimilar函数验证以上数据是否相似,如相似显示“通过”,否则"不通过",所以大家要完成arraysSimilar函数,具体要求,详见任务要求。    
            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)+" 的判断结果不是"+cases[i].expect);                    return false;
                }                
            }            return true;
            
        }();
    document.write("判定结果:"+(result?"通过":"不通过"));

复制代码

这个文件为testData.js。主要任务是完成arraysSimilar函数。

二、arraySimilar函数

1、我的写法

1、判断2个参数是否都是数组,不是就返回false;

2、判断2个数组长度是否一致,不是直接返回fasle;

3、新建2个临时数组temp1,temp2并初始化为0,用来存放arr1和arr2中各种类型的个数。

var temp1 = [0, 0, 0, 0, 0, 0, 0, 0];
var temp2 = [0, 0, 0, 0, 0, 0, 0, 0];

4、遍历2个arr1和arr2,每遍历一个元素,将对应类型加1。

5、完成arr1和arr2的遍历后,通过temp1.toString()和temp2.toString()是否相等得出2个数组是否相似。

复制代码

<!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 + "个值为" + 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 + "个值为" + 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;
        }


    }    //返回参数的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以下) //看了答案发现直接=== 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     //看了答案发现直接=== window 判断就好了
        if (arg instanceof Window) {
            console.log("window");            return "Window";
        }
    }    </script>
    <script src="testData.js"></script></body></html>

复制代码

虽然代码略粗糙,但是功能完成了。网上看了其他人的答案确实不同的人做法不一样,有些值得借鉴的地方。

2、其他答案

建一个类型对象数组obj,初始化为零,arr1遍历时每个元素对应的类型加一,arr2遍历时每个元素对应的类型减一,最终判断obj里所有键的值都为0即相似数组。

复制代码

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;

    }

复制代码

还有一个答案,差不多算标准答案,当然这种题也没有标准答案。和上个答案的差别是,用map(在js中也就是对象)存放数据类型和次数,这个map初始化为{},在后面动态生成的。

复制代码

/**
 * String, Boolean, Number, undefined, null, 函数,日期, window */function arraysSimilar(arr1, arr2) {    // 判断参数,确保arr1, arr2是数组,若不是直接返回false
    if (!(arr1 instanceof Array)        || !(arr2 instanceof Array)) {        return false;
    } 
    // 判断长度
    if (arr1.length !== arr2.length) return false; 
    var i = 0, 
        n = arr1.length, 
        countMap1 = {},  // 用来计算数组元素数据类型个数的map,key是TYPES中的类型字符串,value是数字表示出现次数。
        countMap2 = {},
        t1, t2,
        TYPES = ['string', 'boolean', 'number', 'undefined', 'null',            'function', 'date', 'window']; 
    // 因为是无序的,用一个对象来存储处理过程。key为类型, value为该类型出现的次数。
    // 最后校验:若每一种数据类型出现的次数都相同(或都不存在),则证明同构。
    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;
        }
    } 
    // 因为typeof只能判断原始类型,且无法判断null(返回"object"),所以自己写typeof方法扩展。
    function typeOf(ele) {        var r;        if (ele === null) r = 'null'; // 判断null
        else if (ele instanceof Array) r = 'array';  // 判断数组对象
        else if (ele === window) r = 'window';  // 判断window
        else if (ele instanceof Date) r = 'date'  // 判断Date对象
        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;
}

复制代码

还有一个比较简洁也好理解的解法

复制代码

<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>

复制代码

还有一个精妙的解法,我对这种不感兴趣,没仔细看。

复制代码

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());

}





本文转自 sshpp 51CTO博客,原文链接:http://blog.51cto.com/12902932/1926157,如需转载请自行联系原作者

相关文章
|
1月前
|
JavaScript 前端开发 开发者
如何在 JavaScript 中处理不同类型的错误?
【10月更文挑战第29天】通过对不同类型错误的准确识别和恰当处理,可以提高JavaScript程序的可靠性和稳定性,减少错误对程序运行的影响。
|
2月前
|
JavaScript 前端开发 安全
深入理解TypeScript:增强JavaScript的类型安全性
【10月更文挑战第8天】深入理解TypeScript:增强JavaScript的类型安全性
56 0
|
4月前
|
前端开发 JavaScript 搜索推荐
Next.js 适合什么类型的项目开发?
【8月更文挑战第4天】Next.js 适合什么类型的项目开发?
245 3
|
1月前
|
JavaScript 前端开发 Java
除了 JavaScript,还有哪些编程语言支持 Set 类型
【10月更文挑战第30天】这些编程语言中的 `Set` 类型虽然在语法和具体实现细节上有所不同,但都提供了类似的集合操作功能,方便开发者在不同的编程场景中处理集合相关的数据和逻辑。
|
1月前
|
存储 JavaScript 前端开发
js的基础类型和引用类型
【10月更文挑战第29天】理解 JavaScript 中的基础类型和引用类型的区别对于正确地编写代码和理解程序的行为非常重要。在实际开发中,需要根据具体的需求合理地选择和使用不同的数据类型,以避免出现一些意想不到的错误和问题。同时,在处理引用类型数据时,要特别注意对象的引用关系,避免因共享引用而导致的数据不一致等问题。
|
6月前
|
JavaScript 前端开发
JavaScript中的布尔类型与数字类型详解
JavaScript中的布尔类型与数字类型详解
|
7月前
|
JavaScript 前端开发 安全
使用TypeScript增强JavaScript应用的类型安全性
【5月更文挑战第23天】TypeScript是微软开发的JavaScript超集,引入静态类型检查和面向对象特性,提升代码可维护性和可靠性。它在编译阶段捕获类型错误,增强代码可读性,并通过接口、类、泛型和类型断言等工具确保类型安全。使用TypeScript能有效避免复杂项目中的调试难题,尤其适合大型项目。
|
2月前
|
JavaScript 前端开发
JavaScript返回判断类型有哪些?
JavaScript返回判断类型有哪些?
33 0
|
4月前
|
缓存 JavaScript 前端开发
|
4月前
|
JavaScript 前端开发
在JavaScript如何确认数据的类型?
# `typeof` 与 `instanceof` 数据类型判断 `typeof` 操作符用于确定变量的基本数据类型,例如: - "string" - "number" - "boolean" - "undefined" 但对于引用类型如对象和数组,包括 `null`,它返回 "object"。 `instanceof` 用于检查对象是否为特定构造函数的实例,返回布尔值。它能准确识别数组等复杂类型,通过检查对象的原型链来确定其是否属于某个构造函数的实例。 两者结合使用可全面判断数据类型。
36 2