• JavaScript数据检测


    前言:

    随着编程实践的增加,慢慢发现关于数据类型的检测至关重要。我认为程序就是为了处理数据和展示数据。所以,数据的检测对于编程来说也至关重要。因为只有符合我们预期的输入,才可能产生正确的输出。众所周知,JavaScript是弱类型语言,这带来很多便利的同时,也带来了不少问题。为了减少编程实践中在变量判断方面出现的问题,我们需要对不确定的变量进行检测,以保证处理符合预期的数据。本文是对数据检测的总结。

    1.检测原始值

    ECMAScript 有 5 种原始类型(primitive type),即 Undefined、Null、Boolean、Number 和 String。对于原始值,我们可以使用typeof来检测。

     1 // 检测字符串
     2 typeof "str"  // 返回"string"
     3 
     4 // 检测数字
     5 typeof 123  // 返回"number"
     6 
     7 // 检测布尔值
     8 typeof true  // 返回"boolean"
     9 
    10 // 检测undefined
    11 typeof undefined  // 返回"undefined"
    12 
    13 // 检测null
    14 typeof null  // 返回"object"

    typeof运算符有个很独特的地方就是,当我们检测一个未声明的变量时也不会报错。未定义的变量和undefined的变量通过typeof检测都将返回“undefined”。

    还有就是当我们用typeof检测null变量时,返回的是“object”而不是“null”。null一般是不用于检测语句的,简单地和null比较通常不会包含足够的信息以判断值的类型是否合法。但,当所期望的值确定是null,则可以和null直接比较(===和!==)。

    2.检测引用值

    引用值也称为对象,在js中除了原始值之外的值都是引用,如Object、Function、Array、String、Boolean、Number、Date等。由于使用typeof检测引用类型时,返回的是“object”,我们并不能真正的获得引用类型的详细信息。而instanceof运算符可以解决这个问题,instanceof 运算符与 typeof 运算符相似,用于识别正在处理的对象的类型。与 typeof 方法不同的是,instanceof 方法要求开发者明确地确认对象为某特定类型。基本用法为:

    1 value instanceof constructor

    其含义是判断一个value是否为constructor对象的实例,如果是则返回true,否则返回false。

    instanceof并不仅仅止步于检测构造这个对象的构造器,它还会沿着原型链进行检测。示例如下:

    1 var now = new Date();
    2 
    3 console.log(now instanceof Date);  // 输出:true
    4 console.log(now instanceof Object); // 输出:true

    在默认情况下,每个对象都继承自Object,因此每个对象的 value instanceof Object都会返回true,使用这个方法来判断对象是否属于某个特定类型的做法并非最佳。

    instanceof运算符也可以用来检测自定义类型,示例如下:

     1 function BasicType() {
     2      this.property=true;
     3 
     4      this.getBasicValue = function(){
     5      return this.property;
     6       };
     7 }
     8 
     9 function NewType() {
    10      this.subproperty=false;
    11 }
    12 
    13 NewType.prototype = new BasicType(); 
    14 var test = new NewType();
    15 
    16 console.log(test instanceof NewType);   // 输出:true
    17 console.log(test instanceof BasicType);   // 输出:true
    18 console.log(test instanceof Object);   // 输出:true

    在JavaScript中检测自定义类型时,最好的做法就是使用instanceof运算符,这也是唯一的方法。

    3.检测属性

    另外一种用到null(以及undefined)的场景是当检测一个属性是否在对象中存在时,比如:

     1 // 不好的写法:检测假值
     2 if (object[propertyName]) {
     3     // code
     4 }
     5 
     6 // 不好的写法:和null比较
     7 if (object[propertyName] != null) {
     8     // code
     9 }
    10 
    11 // 不好的写法:和undefined比较
    12 if (object[propertyName] != undefined) {
    13     // code
    14 }

    在上例中,实际上是通过给定的属性名来检测属性的值,而非判断属性是否存在,因为当属性值为假值时结果超出我们的预期,比如0、""、false、null和undefined时。如果我们要检测的属性值为null或者undefined时,以上是哪个判断都会出错。

    判断属性是否存在的最好方法是使用in运算符。in运算符只会判断属性存在与否,而不管属性值,这样就避免了上面问题的产生。

     1 var object = {
     2     count: 0,
     3     name: null
     4 };
     5 
     6 // 好的写法
     7 if ("count" in object) {
     8     // 执行代码
     9 };
    10 
    11 // 不好的写法:检测假值
    12 if (object["count"]) {
    13     // 不执行代码
    14 };
    15 
    16 // 好的写法
    17 if ("name" in object) {
    18     // 执行代码
    19 };
    20 
    21 // 不好的写法:检测是否为null
    22 if (object["name"] != null) {
    23     // 不执行代码
    24 };

    但还有一点需要注意,in运算符也会检测原型链上的所有属性,无论是实例上还是继承对象的原型上具有目标属性,都会返回true。如果需要检测对象的某个属性是否存在,则需要使用hasOwnProperty()方法。所有继承自Object的JS对象都有这个方法,如果实例中包含这个属性则返回true(如果这个属性只存在在原型中则返回false)。

    然而,在IE8以及更早版本的IE中,DOM对象并非继承自Object,也就不包含hasOwnProperty()方法。我们在使用hasOwnProperty()方法时,应该先检测是否存在这个方法。

     1 var object = {
     2     count = 0,
     3     name = null
     4 };
     5 
     6 // 对于所有的非DOM对象来说,这是最好的实现
     7 if (Object.hasOwnProperty("name")) {
     8     // 执行代码
     9 }
    10 
    11 // 对于所有不确定是否为DOM的对象来说,应该这样实现
    12 if ("hasOwnProperty" in Object && Object.hasOwnProperty("name")) {
    13     // 执行代码
    14 }

    不管在任何情况下检测属性的存在性,最好使用in运算符或者hasOwnProperty(),这样可以避免很多bug。

  • 相关阅读:
    关于使用quartz动态增删改定时任务
    关于chrome被篡改主页修复方法
    关于git被误删除的分支还原问题
    mysql数据库备份bat脚本
    同步数据库bat脚本
    读取spring boot项目中resource目录下的文件
    使用Java进行udp-demo编程时碰到的consumer和producter无法连接并报出“java.net.SocketException: Can't assign requested address”问题
    关于在项目中遇到MySQL数据库死锁的问题
    Gitlab仓库搭建及在Linux/windows中的免密使用
    GIT
  • 原文地址:https://www.cnblogs.com/syfwhu/p/4819060.html
Copyright © 2020-2023  润新知