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 的方法重载效果
Aug 07 Javascript
Javascript 遮罩层和加载效果代码
Aug 01 Javascript
js转义字符介绍
Nov 05 Javascript
Area 区域实现post提交数据的js写法
Apr 22 Javascript
JavaScript实现防止网页被嵌入Frame框架的代码分享
Dec 29 Javascript
jQuery获取页面元素绝对与相对位置的方法
Jun 10 Javascript
javascript RegExp 使用说明
May 21 Javascript
jquery实现焦点轮播效果
Feb 23 Javascript
jQuery插件FusionCharts绘制的3D双柱状图效果示例【附demo源码】
Apr 20 jQuery
Vue.js组件间通信方式总结【推荐】
Nov 23 Javascript
JS中数组实现代码(倒序遍历数组,数组连接字符串)
Dec 29 Javascript
JavaScript基于用户照片姓名生成海报
May 29 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&amp;java(二)
2006/10/09 PHP
php 中英文语言转换类代码
2011/08/11 PHP
yii框架结合charjs统计上一年与当前年数据的方法示例
2020/04/04 PHP
JS代码放在head和body中的区别分析
2011/12/01 Javascript
Three.js源码阅读笔记(Object3D类)
2012/12/27 Javascript
js实现动态添加、删除行、onkeyup表格求和示例
2013/08/18 Javascript
动态标签 悬停效果 延迟加载示例代码
2013/11/21 Javascript
js面向对象之公有、私有、静态属性和方法详解
2015/04/17 Javascript
AngularJS 工作原理详解
2016/08/18 Javascript
angularjs 源码解析之injector
2016/08/22 Javascript
基于JavaScript实现淘宝商品广告效果
2017/08/10 Javascript
JavaScript重复元素处理方法分析【统计个数、计算、去重复等】
2017/12/14 Javascript
在vue项目中使用Nprogress.js进度条的方法
2018/01/31 Javascript
200行代码实现blockchain 区块链实例详解
2018/03/14 Javascript
解决vue的变量在settimeout内部效果失效的问题
2018/08/30 Javascript
微信小程序实现发送验证码按钮效果
2018/12/20 Javascript
JS中实现一个下载进度条及播放进度条的代码
2019/06/10 Javascript
vscode vue 文件模板的配置方法
2019/07/23 Javascript
微信小程序网络请求实现过程解析
2019/11/06 Javascript
Python 单元测试(unittest)的使用小结
2018/11/14 Python
Python3.5 Pandas模块缺失值处理和层次索引实例详解
2019/04/23 Python
Python 安装第三方库 pip install 安装慢安装不上的解决办法
2019/06/18 Python
Python 3.8正式发布,来尝鲜这些新特性吧
2019/10/15 Python
wxPython实现带颜色的进度条
2019/11/19 Python
Python使用指定字符长度切分数据示例
2019/12/05 Python
python中四舍五入的正确打开方式
2021/01/18 Python
澳大利亚波西米亚风连衣裙在线商店:Fortunate One
2019/04/01 全球购物
SneakerStudio英国:最佳运动鞋商店
2019/05/22 全球购物
银行实习自我鉴定
2013/10/12 职场文书
互联网创业计划书的书写步骤
2014/01/28 职场文书
六年级数学教学反思
2014/02/03 职场文书
飘柔洗发水广告词
2014/03/14 职场文书
《中国梦我的梦》中学生演讲稿
2014/08/20 职场文书
政协常委会议主持词
2015/07/03 职场文书
写一个Python脚本下载哔哩哔哩舞蹈区的所有视频
2021/05/31 Python
oracle重置序列从0开始递增1
2022/02/28 Oracle