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控制div及网页相关属性的代码
Dec 19 Javascript
GridView中获取被点击行中的DropDownList和TextBox中的值
Jul 18 Javascript
javascript实现存储hmtl字符串示例
Apr 25 Javascript
jquery自定义下拉列表示例
Apr 25 Javascript
js打开windows上的可执行文件示例
May 27 Javascript
jQuery实现仿腾讯视频列表分页效果的方法
Aug 07 Javascript
jquery实现平滑的二级下拉菜单效果
Aug 26 Javascript
jQuery中layer分页器的使用
Mar 13 Javascript
详解vue2.0 不同屏幕适配及px与rem转换问题
Feb 23 Javascript
Vue+ElementUI实现表单动态渲染、可视化配置的方法
Mar 07 Javascript
Vue2.5学习笔记之如何在项目中使用和配置Vue
Sep 26 Javascript
webpack优化之代码分割与公共代码提取详解
Nov 22 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
服务器端解压缩zip的脚本
2006/12/22 PHP
php 5.3.5安装memcache注意事项小结
2011/04/12 PHP
给初学者的30条PHP最佳实践(荒野无灯)
2011/08/02 PHP
PHP编程中的常见漏洞和代码实例
2014/08/06 PHP
php无限级评论嵌套实现代码
2018/04/18 PHP
Js 随机数产生6位数字
2010/05/13 Javascript
jquery.tmpl JQuery模板插件
2011/10/10 Javascript
Package.js  现代化的JavaScript项目make工具
2012/05/23 Javascript
JavaScript实现的一个倒计时的类
2015/03/12 Javascript
jQuery简单实现两级下拉菜单效果代码
2015/09/15 Javascript
JavaScript弹出对话框的三种方式
2016/03/23 Javascript
JSON对象 详解及实例代码
2016/10/18 Javascript
基于Bootstrap的Java开发问题汇总(Spring MVC)
2017/01/15 Javascript
解读ES6中class关键字
2017/11/20 Javascript
vue项目关闭eslint校验
2018/03/21 Javascript
微信小程序仿知乎实现评论留言功能
2018/11/28 Javascript
layui对工具条进行选择性的显示方法
2019/09/19 Javascript
js禁止查看源文件屏蔽Ctrl+u/s、F12、右键等兼容IE火狐chrome
2020/10/01 Javascript
python数据结构之二叉树的建立实例
2014/04/29 Python
Python程序设计入门(3)数组的使用
2014/06/16 Python
Python中模块string.py详解
2017/03/12 Python
python 读写中文json的实例详解
2017/10/29 Python
python 实现求解字符串集的最长公共前缀方法
2018/07/20 Python
python 在sql语句中使用%s,%d,%f说明
2020/06/06 Python
咖啡为什么会有酸味?你喝到的咖啡為什麼是酸的?
2021/03/17 冲泡冲煮
利用html5 file api读取本地文件示例(如图片、PDF等)
2018/03/07 HTML / CSS
植物选择:Botanic Choice
2017/02/15 全球购物
Nike瑞士官网:Nike CH
2021/01/18 全球购物
2014年村官工作总结
2014/11/24 职场文书
年度考核登记表个人总结
2015/03/06 职场文书
2015年个人思想总结
2015/03/09 职场文书
医药公司开票员岗位职责
2015/04/15 职场文书
小学语文教师竞聘演讲稿范文
2019/08/09 职场文书
MySQL root密码的重置方法
2021/04/21 MySQL
Python中super().__init__()测试以及理解
2021/12/06 Python
如何使用python包中的sched事件调度器
2022/04/30 Python