Javascript类型判断相关例题及解析


Posted in Javascript onAugust 26, 2020

题目:

请在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());
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
增强的 JavaScript 的 trim 函数的代码
Aug 13 Javascript
基于jquery的商品展示放大镜
Aug 07 Javascript
用js来获取上传的文件名纯粹是为了美化而用
Oct 23 Javascript
js判断页面中是否有指定控件的简单实例
Mar 04 Javascript
举例讲解Node.js中的Writable对象
Jul 29 Javascript
JS组件Bootstrap Select2使用方法解析
May 30 Javascript
Move.js入门
Feb 08 Javascript
使用jquery DataTable和ajax向页面显示数据列表的方法
Aug 09 jQuery
vue微信分享的实现(在当前页面分享其他页面)
Apr 16 Javascript
WEB前端性能优化的7大手段详解
Feb 04 Javascript
vue实现多个echarts根据屏幕大小变化而变化实例
Jul 19 Javascript
JavaScript 反射学习技巧
Oct 16 Javascript
Javascript基于OOP实实现探测器功能代码实例
Aug 26 #Javascript
Javascript如何实现扩充基本类型
Aug 26 #Javascript
Javascript var变量删除原理及实现
Aug 26 #Javascript
js实现车辆管理系统
Aug 26 #Javascript
js实现飞机大战小游戏
Aug 26 #Javascript
JS面向对象实现飞机大战
Aug 26 #Javascript
JavaScript Image对象实现原理实例解析
Aug 26 #Javascript
You might like
JAVA/JSP学习系列之四
2006/10/09 PHP
thinkphp3.0 模板中函数的使用
2012/11/13 PHP
浅谈web上存漏洞及原理分析、防范方法(安全文件上存方法)
2013/06/29 PHP
iis6手工创建网站后无法运行php脚本的解决方法
2017/06/08 PHP
jQuery fadeTo方法调整图片的透明度使用介绍
2013/05/06 Javascript
自制的文件上传JS控件可支持IE、chrome、firefox etc
2014/04/18 Javascript
jQuery中focus事件用法实例
2014/12/26 Javascript
JS实现漂亮的淡蓝色滑动门效果代码
2015/09/23 Javascript
avalon js实现仿google plus图片多张拖动排序附源码下载
2015/09/24 Javascript
javascript html5 canvas实现可拖动省份的中国地图
2016/03/11 Javascript
浅谈JavaScript的内置对象和浏览器对象
2016/06/03 Javascript
浅谈jQuery hover(over, out)事件函数
2016/12/03 Javascript
简单实现Vue的observer和watcher
2016/12/21 Javascript
浅谈ES6新增的数组方法和对象
2017/08/08 Javascript
详解Nuxt.js Vue服务端渲染摸索
2018/02/08 Javascript
Vue实现远程获取路由与页面刷新导致404错误的解决
2019/01/31 Javascript
Javascript Worker子线程代码实例
2020/02/20 Javascript
jQuery实现简单轮播图效果
2020/12/27 jQuery
解密Python中的描述符(descriptor)
2015/06/03 Python
在Mac OS上搭建Python的开发环境
2015/12/24 Python
Python基础语言学习笔记总结(精华)
2017/11/14 Python
利用python为运维人员写一个监控脚本
2018/03/25 Python
浅谈Pandas中map, applymap and apply的区别
2018/04/10 Python
python直接获取API传递回来的参数方法
2018/12/17 Python
python输出带颜色字体实例方法
2019/09/01 Python
python matplotlib折线图样式实现过程
2019/11/04 Python
python speech模块的使用方法
2020/09/09 Python
Python 按比例获取样本数据或执行任务的实现代码
2020/12/03 Python
解决selenium+Headless Chrome实现不弹出浏览器自动化登录的问题
2021/01/09 Python
Microsoft新加坡官方网站:购买微软最新软件和技术产品
2016/10/28 全球购物
党风廉政承诺书
2014/03/27 职场文书
房屋继承公证书
2014/04/10 职场文书
地下停车场租赁协议范本
2014/10/07 职场文书
Nginx tp3.2.3 404问题解决方案
2021/03/31 Servers
这样写python注释让代码更加的优雅
2021/06/02 Python
python之np.argmax()及对axis=0或者1的理解
2021/06/02 Python