当前位置 : 主页 > 手机教程 > 手机资讯 >

javaScript中一些常见的数据类型检查校验

来源:互联网 收集:自由互联 发布时间:2023-01-25
目录 前言 常见的几种数据校验方式 typeof操作符 instanceof constructor call apply Object.prototype.toString结合Function.prototype.call apply 其他校验数据类型的方法: 总结 源码地址 前言 在JavaScript中,
目录
  • 前言
  • 常见的几种数据校验方式
    • typeof操作符
    • instanceof
    • constructor
    • call && apply
    • Object.prototype.toString结合Function.prototype.call && apply
    • 其他校验数据类型的方法:
  • 总结
    • 源码地址

      前言

      在JavaScript中,数据类型分为两大类,一种是基础数据类型,另一种则是复杂数据类型,又叫引用数据类型

      • 基础数据类型:数字Number 字符串String 布尔Boolean Null Undefined Symbols BigInt
      • 引用数据类型:日期Dete,对象Object,数组Array,方法Function, 正则regex,带键的集合:Maps, Sets, WeakMaps, WeakSets

      基础数据类型和引用数据类型的区别,在之前深拷贝的文章中提到过,这里不做详细赘述。

      传送门:javaScript中深拷贝和浅拷贝简单梳理

      常见的几种数据校验方式

      接下来会针对下面几种数据类型,进行校验

      // 基本数据类型
      let str = "abc";
      let num = 123;
      let boo = true;
      let undef = undefined;
      let testNull = null;
      let symb = Symbol("user");
      let bigInt = BigInt(9007199254740999);
      
      // 复杂-引用数据类型
      let arr = [1, 2, 3, 4];
      let func = function () {};
      let obj = {};
      let date1 = new Date();
      let setObj1 = new Set();
      let setObj2 = new Set([1, 2, 3]);
      let mapObj = new Map();
      

      typeof操作符

      typeof操作符,会返回一个字符串,表示未经计算的操作数的类型

      /**
       * typeof 操作符
       *
       * 返回一个字符串,表示未经计算的操作数的类型。
       *
       * */
      console.log(typeof str); //  string
      console.log(typeof num); //  number
      console.log(typeof boo); //  boolean
      console.log(typeof undef); //  undefined
      console.log(typeof testNull); //  object
      console.log(typeof symb); //  symbol
      console.log(typeof bigInt); //  bigint
      console.log(typeof Object(bigInt)); // object
      console.log(typeof arr); //  object
      console.log(typeof func); //  function
      console.log(typeof obj); //  object
      console.log(typeof date1); //  object
      console.log(typeof setObj1); //  object
      console.log(typeof setObj2); //  object
      console.log(typeof mapObj); //  object
      

      小结

      使用typeof操作符的时候,我们可以看到一些较为特殊的情况:

      • null,数组array,set,map 返回的是对象object

      instanceof

      instanceof用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。

      /**
       *
       * instanceof
       *
       * 用于检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。
       *
       * */
      console.log(str instanceof String); // false
      console.log(new String("abc") instanceof String); // true
      console.log(num instanceof Number); // false
      console.log(new Number(123) instanceof Number); // true
      console.log(boo instanceof Boolean); // false
      console.log(new Boolean(true) instanceof Boolean); // false
      console.log(undef instanceof undefined);
      // Uncaught TypeError: Right-hand side of 'instanceof' is not an object
      console.log(testNull instanceof null);
      // Uncaught TypeError: Right-hand side of 'instanceof' is not an object
      console.log(symb instanceof Symbol); // false 
      // Symbol不是构造函数,没有new操作符
      console.log(bigInt instanceof BigInt); // false
      console.log(Object(BigInt("22")) instanceof Object); // true
      console.log(Object(BigInt("22")) instanceof BigInt); // true
      console.log(arr instanceof Array); // true
      console.log(arr instanceof Object); // true
      console.log(func instanceof Function); // true
      console.log(func instanceof Object); // true
      console.log(obj instanceof Object); // true
      console.log(obj instanceof Function); // false
      console.log(null instanceof Object); // false
      console.log(date1 instanceof Object); // true
      console.log(setObj1 instanceof Object); //  true
      console.log(setObj2 instanceof Object); //  true
      console.log(mapObj instanceof Object); //  true
      console.log(setObj1 instanceof Array); //  false
      console.log(setObj2 instanceof Array); //  false
      console.log(mapObj instanceof Array); //  false
      

      constructor

      /**
       * constructor
       *
       * 返回创建实例对象的 构造函数的引用。
       *
       * 注意,此属性的值是对函数本身的引用,而不是一个包含函数名称的字符串
       *
       * 构造函数.prototype.constructor()
       *
       * */
       
      // 基本数据类型
      let str = "abc";
      let num = 123;
      let boo = true;
      let undef = undefined;
      let testNull = null;
      let symb = Symbol("user");
      let bigInt = BigInt(9007199254740999);
      // 复杂-引用数据类型
      let arr = [1, 2, 3, 4];
      let func = function () {};
      let obj = {};
      let date1 = new Date();
      function constructorFn() {
        this.name = "11";
      }
      let con1 = new constructorFn();
      let setObj1 = new Set();
      let setObj2 = new Set([1, 2, 3]);
      let mapObj = new Map(); 
      console.log(str.constructor); // String
      console.log(num.constructor); // Number
      console.log(boo.constructor); // Boolean
      // console.log(testUndefined.constructor); // Cannot read property 'constructor' of undefined
      // console.log(testNull.constructor); // Cannot read property 'constructor' of null
      console.log(symb.constructor); // Symbol
      console.log(bigInt.constructor); // BigInt
      console.log(arr.constructor); // Array
      console.log(func.constructor); // Function
      console.log(obj.constructor); // Object
      console.log(date1.constructor); // Date
      console.log(constructorFn.constructor); // Function
      console.log(con1.constructor); // constructorFn
      console.log(setObj1.constructor); // Set
      console.log(setObj2.constructor); // Set
      console.log(mapObj.constructor); // Map
      /**
       *
       * 构造函数校验
       *
       * */
      console.log(Function.constructor); // Function
      console.log(Object.constructor); // Function
      console.log(Array.constructor); // Function
      console.log(Date.constructor); // Function
      

      Object.prototype.toString.call && Object.prototype.toString.apply
      Object.prototype.toString()

      在使用Object.prototype.toString.call或者Object.prototype.toString.apply检查数据类型之前,我们先了解一下Object.prototype.toString和JavaScript中的构造函数Function的原型方法apply和call:

      /**
       * 返回一个表示该对象的字符串
       *
       * Object.prototype.toString()
       *
       * 每个对象都有一个 toString() 方法,当该对象被表示为一个文本值时,或者一个对象以预期的字符串方式引用时自动调用。
       * 默认情况下,toString() 方法被每个 Object 对象继承。
       *
       * 如果此方法在自定义对象中未被覆盖,toString() 返回 "[object type]",其中 type 是对象的类型。以下代码说明了这一点:
       *
       * */
      
      let isObj = { name: "zhangsan" };
      let isBoolean = true;
      let isNumber = new Number(123);
      let isString = "abc";
      let isFun = new Function();
      console.log(isObj.toString()); // [object Object]
      console.log(isBoolean.toString()); // true
      console.log(isNumber.toString()); // 123
      console.log(isString.toString()); // abc
      console.log(new Date().toString()); // Thu Apr 28 2022 16:37:19 GMT+0800 (中国标准时间)
      console.log(isFun.toString()); // function anonymous() {}
      

      call && apply

      /**
       *
       * call() 使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数,function.call(thisArg, arg1, arg2, ...)
       *
       * apply() 使用一个指定的 this 值和单独给出的一个或多个参数来调用一个函数,unc.apply(thisArg, [argsArray])
       *
       * */
      // call基本使用;
      function a() {
      	console.log(this);
      }
      function b() {
      	console.log(this);
      }
      a.call(b); //		function b() {}
      b.call(a); //		function a() {}
      

      call和apply最简单的例子表明了,改变了当前方法的this指向

      同时这两个方法的区别在于传参的方式

      Object.prototype.toString结合Function.prototype.call && apply

      /**
       *
       * 使用 toString() 检测对象类型可以通过 toString() 来获取每个对象的类型。
       * 为了每个对象都能通过 Object.prototype.toString() 来检测,
       * 需要以 Function.prototype.call() 或者 Function.prototype.apply() 的形式来调用,传递要检查的对象作为第一个参数,称为 thisArg。
       *
       * 那么 Object.prototype.toString 相当于 原生构造函数的实例化对象isNumber,传参数给Object.prototype.toString执行
       * 实际上相当于 toString.call(new ***);
       *
       * */
       
      let str = "abc";
      let num = 123;
      let boo = true;
      let undef = undefined;
      let testNull = null;
      let symb = Symbol("user");
      let bigInt = BigInt(9007199254740999);
      // 复杂-引用数据类型
      let arr = [1, 2, 3, 4];
      let func = function () {};
      let obj = {};
      let date1 = new Date();
      function testFun() {}
      let newTest = new testFun();
      let newFun = new Function();
      let setObj1 = new Set();
      let setObj2 = new Set([1, 2, 3]);
      let mapObj = new Map();
      console.log(Object.prototype.toString.apply(new String("sss"))); // [object String]
      console.log(Object.prototype.toString.apply(str)); // [object String]
      console.log(Object.prototype.toString.call(num)); // [object Number]
      console.log(Object.prototype.toString.call(boo)); // [object Boolean]
      console.log(Object.prototype.toString.call(undef)); // [object Undefined]
      console.log(Object.prototype.toString.call(testNull)); // [object Null]
      console.log(Object.prototype.toString.call(symb)); // [object Symbol]
      console.log(Object.prototype.toString.call(Object(bigInt))); // [object BigInt]
      console.log(Object.prototype.toString.call(bigInt)); // [object BigInt]
      console.log(Object.prototype.toString.apply(arr)); // [object Array]
      console.log(Object.prototype.toString.call(func)); // [object Function]
      console.log(Object.prototype.toString.call(obj)); // [object Object]
      console.log(Object.prototype.toString.call(date1)); // [object Date]
      console.log(Object.prototype.toString.call(testFun)); // [object Function]
      console.log(Object.prototype.toString.call(newTest)); // [object Object]
      console.log(Object.prototype.toString.call(newFun)); // [object Function]
      console.log(Object.prototype.toString.call(setObj1)); // [object Set]
      console.log(Object.prototype.toString.call(setObj2)); // [object Set]
      console.log(Object.prototype.toString.call(mapObj)); // [object Map]
      

      其他校验数据类型的方法:

      判断是否是数组:

      console.log(Array.isArray([1, 2])); // true

      判断一个对象是否是空对象

      // 判断空对象
      function isEmptyObj(obj) {
        for (name in obj) {
          console.log(name);
          return false; // 不是空对象
        }
        return true;
      }
      console.log(isEmptyObj({}));  // true
      

      总结

      • 不管是typeof操作符,还是其他的操作方法,都有各自的缺陷
      • 在日常的开发过程中,我们需要知道当前操作的是对象,还是构造函数生成的对象或者方法,才能针对当前需要判断的数据类型,采用最适合的方法
      • Object.prototype.toString.call或者Object.prototype.toString.apply应该是最完善的方法,在我们不确定是否是引用类型或者基本数据类型的时候,建议作为首选
      • 在了解这些判断数据类型的方式之前或者说存有疑问:为什么array数组在使用instanceof和typeof 校验Object的时候都成立,这时候需要去了解一下引用数据类型的具体内容
      • 以上判断数据类型的方法,可以在项目开发过程中,可以写入到utils公共方法当中,作为开发中进行使用。

      更多用法等待补充。

      到此这篇关于javaScript中一些常见的数据类型检查校验的文章就介绍到这了,更多相关JS数据类型检查校验内容请搜索自由互联以前的文章或继续浏览下面的相关文章希望大家以后多多支持自由互联!

      源码地址

      码云 https://gitee.com/lewyon/vue-note
      githup https://github.com/akari16/vue-note

      上一篇:javaScript深拷贝和浅拷贝的简单介绍
      下一篇:没有了
      网友评论