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 相关文章推荐
Js 刷新框架页的代码
Apr 13 Javascript
基于jquery的网页SELECT下拉框美化代码
Oct 28 Javascript
js中用window.open()打开多个窗口的name问题
Mar 13 Javascript
javascript制作网页图片上实现下雨效果
Feb 26 Javascript
javascript跨域方法、原理以及出现问题解决方法(详解)
Aug 06 Javascript
node.js 动态执行脚本
Jun 02 Javascript
js移动焦点到最后位置的简单方法
Nov 25 Javascript
three.js绘制地球、飞机与轨迹的效果示例
Feb 28 Javascript
微信小程序实现倒计时60s获取验证码
Apr 17 Javascript
JS原型prototype和__proto__用法实例分析
Mar 14 Javascript
基于JavaScript实现十五拼图代码实例
Apr 26 Javascript
vue 实现根据data中的属性值来设置不同的样式
Aug 04 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
PHP获取某个月最大天数(最后一天)的方法
2015/07/29 PHP
php面向对象程序设计中self与static的区别分析
2019/05/21 PHP
详解阿里云视频直播PHP-SDK接入教程
2020/07/09 PHP
javascript之通用简单的table选项卡实现(二)
2010/05/09 Javascript
js将控件隐藏的方法及display属性介绍
2013/07/04 Javascript
使用cluster 将自己的Node服务器扩展为多线程服务器
2014/11/10 Javascript
兼容主流浏览器的JS复制内容到剪贴板
2014/12/12 Javascript
thinkphp 表名 大小写 窍门
2015/02/01 Javascript
JavaScript使用Max函数返回两个数字中较大数的方法
2015/04/06 Javascript
WordPress中鼠标悬停显示和隐藏评论及引用按钮的实现
2016/01/12 Javascript
基于Three.js插件制作360度全景图
2016/11/29 Javascript
JS声明式函数与赋值式函数实例分析
2016/12/13 Javascript
基于JavaScript实现多级菜单效果
2017/07/25 Javascript
node通过npm写一个cli命令行工具
2017/10/12 Javascript
vue 使用html2canvas将DOM转化为图片的方法
2018/09/11 Javascript
Vue之封装公用变量以及实现方式
2020/07/31 Javascript
解决vant-UI库修改样式无效的问题
2020/11/03 Javascript
[18:20]DOTA2 HEROS教学视频教你分分钟做大人-昆卡
2014/06/11 DOTA
[01:05:52]DOTA2-DPC中国联赛 正赛 Ehome vs Aster BO3 第一场 2月2日
2021/03/11 DOTA
Python实现TCP协议下的端口映射功能的脚本程序示例
2016/06/14 Python
Python多进程multiprocessing用法实例分析
2017/08/18 Python
python mysql断开重连的实现方法
2019/07/26 Python
matplotlib jupyter notebook 图像可视化 plt show操作
2020/04/24 Python
Django-Scrapy生成后端json接口的方法示例
2020/10/06 Python
墨西哥网上购物:Linio墨西哥
2016/10/20 全球购物
STAUD官方网站:洛杉矶独有的闲适风格
2019/04/11 全球购物
社会实践自我鉴定
2013/11/07 职场文书
学生打架检讨书1000字
2014/01/16 职场文书
先进德育工作者事迹材料
2014/01/24 职场文书
制作部班长职位说明书
2014/02/26 职场文书
争先创优个人总结
2015/03/04 职场文书
酒店人事专员岗位职责
2015/04/07 职场文书
电影开国大典观后感
2015/06/04 职场文书
公司的力量观后感
2015/06/05 职场文书
生鲜超市—未来中国最具有潜力零售业态
2019/08/02 职场文书
Pandas数据结构之Series的使用
2022/03/31 Python