• JavaScript 数据类型判断


    JavaScript 的数据类型分为两类:原始类型(基本类型)和对象类型(引用类型)。原始类型包括数字、字符串和布尔值,另外有两个特殊的原始值:null 和 undefined,除此之外的都是对象。对象还包括两种特殊的对象:数组和函数。

    下面所有代码表达式如果返回值为 true 表示判断成立,否则不成立,变量 obj 表示需要判断的值。

    通用方法

    使用 typeof 运算符

    判断数据类型可以使用 typeof 运算符,返回值是一个代表数据类型的字符串(注意是字符串,而且是小写的):

    typeof 1             // 'number'
    typeof 'abc'         // 'string'
    typeof false         // 'boolean'
    typeof undefined     // 'undefined'
    typeof null          // 'object'
    typeof {x: 1}        // 'object'
    typeof [1, 2, 3]     // 'object'
    typeof function() {} // 'function'
    

    typeof 运算符可以有效判断数字、字符串、布尔值和 undefined 等原始类型,不过在面对数组和对象时就无能为力了。

    借用 Object.prototype.toString() 方法

    借用 Object.prototype.toString() 方法可以得到一个表示对象的类型的字符串:

    var toString = Object.prototype.toString;
    toString.call('abc')    // '[object String]'
    toString.call(true)     // '[object Boolean]'
    toString.call([])       // '[object Array]'
    toString.call({})       // '[object Object]'
    toString.call(/./)      // '[object RegExp]'
    toString.call(new Date) // '[object Date]'
    toString.call(Math)     // '[object Math]'
    

    使用该方法可以有效判断数组、函数、日期、正则表达式等对象类型(引用类型)。在 ECMAScript 5 中还可以用这个方法来判断 null
    undefined

    toString.call(null)      // '[object Null]'
    toString.call(undefined) // '[object Undefined]'
    

    下面是一些特殊情况。

    原始类型(基本类型)

    数字

    使用 typeof 运算符可以判断任意数字、NaN 或者 Infinity

    typeof NaN      // 'number'
    typeof Infinity // 'number'
    

    如果要排除 NaNInfinity 可以使用 isFinite() 方法,不过 isFinite() 方法试图将一些非数字类型转换为数字,因此需要双重保险:

    typeof obj === 'number' && isFinite(obj)
    

    上面的表达式如果返回为 true 则保证了变量 obj 是数字类型的同时不是 NaN 或者 Infinity,毕竟我们不希望这两个特殊数值参与数学运算。ECMAScript 6 增加的 Number.isFinite() 方法有同样效果。

    整数

    判断一个数是整数并且在安全范围内,利用整数取整后还是与自身相等的特点:

    typeof obj === 'number' && isFinite(obj)
      && obj > -9007199254740992
      && obj < 9007199254740992
      && Math.floor(obj) === obj
    

    NaN

    全局的 isNaN() 方法也试图将一些非数字类型隐式转换为数字,如果转换成功,它会认为这个值是一个数字,否则会认为这是一个 NaN

    isNaN(NaN)       // true
    isNaN(0/0)       // true 0 除以 0 的结果为 NaN
    isNaN('1')       // false 字符串 '1' 可以隐式转换为数字 1
    isNaN(true)      // false 布尔值 true 可以隐式转换为数字 1
    isNaN([])        // false 空数组可以隐式转换为数字 0
    isNaN(Infinity)  // false
    isNaN('abc')     // true
    isNaN(undefined) // true
    

    字符串 'abc'undefined 都不能隐式转换为一个数字,所以被判断为是一个 NaN

    NaN 是一个特殊数值,它不等于任何值,甚至不等于它自己,因此判断一个值为 NaN 的最好方式是判断它是一个数字类型同时不等于自身:

    typeof obj === 'number' && obj != +obj
    

    ECMAScript 6 增加的 Number.isNaN() 方法更好地解决了这个问题,只有值为 NaN 的时候才会返回 true

    Number.isNaN(NaN)        // true
    Number.isNaN(Number.NaN) // true
    Number.isNaN(0/0)        // true
    Number.isNaN(Infinity)   // false
    Number.isNaN('abc')      // false
    Number.isNaN(undefined)  // false
    

    可以看出 Number.isNaN() 方法和 isNaN() 方法是不一样的。Number.isNaN() 方法仅用于判断是否是特殊值 NaN

    布尔值

    布尔值不是 true 就是 false,可以使用 typeof 运算符,也可以像下面这样判断:

    obj === true || obj === false
    

    Undefined

    在 ECMAScript 3 中 undefined 是可读写的,所以直接与 undefined 作比较返回的结果不一定是准确的,像这样 var undefined = 1 在有些实现中是可以改变其值的,此时再与之做比较得到的结果就有点出人意料了,通常情况下还是使用 typeof 运算符来判断:

    typeof obj === 'undefined'
    

    不过使用 typeof 运算符有一个不好的地方是不能区分未定义的变量和值为 undefined 的变量(两者还是有区别的),另外一种方式是使用 void 运算符,因为它的运算结果总是返回 undefined

    obj === void 0
    

    Null

    使用 typeof 运算符判断 null 将会返回 'object',这明显不是想要的,所以最好的方式是直接与 null 值进行比较:

    obj === null
    

    这里必须使用 ===,因为 undefined == null 也会返回 true

    存在判断

    对值为 nullundefined 的变量读取属性时会引发错误,因此有时候需要做存在判断,简单地使用 if 语句来判断,会将那些可以隐式转换为 false 的值也一概排除掉了,比如数字0、空字符串、空数组(这里有个错误,空数组单独放在 if 语句里面将会转换为 true,而作比较的时候是与 false 相等的,比如 [] == false)之类的,它们都可以隐式转换为 false,因为 undefined == null 会返回 true,而和其它任何非 null 或者 undefined 的值比较都会返回 false,所以更好的办法是直接与 null 值做比较:

    if (obj != null) {
      obj.property;
    }
    

    这样就可以判断变量 obj 既不是 undefined 也不是 null,或者像下面这样判断:

    typeof obj !== 'undefined' && obj !== null
    

    通过存在判断才可以放心使用 . 语法获取属性。

    对象类型(引用类型)

    对象

    要区别 null 和其它对象可以像下面这样判断,因为 null 值可以隐式转换为 false

    obj && typeof obj === 'object'
    

    这样判断就可以把 null 给排除掉,变量 obj 是对象或者数组或者其它对象(不包括函数)。下面是另外一种方法:

    obj === Object(obj)
    

    使用 Object() 方法如果传入的参数不是对象将会被转换为对象,否则,只是简单地将传入的参数返回。该方法可以判断所有对象,包括函数。

    数组

    判断数组的方法:

    Object.prototype.toString.call(obj) === '[object Array]'
    

    ECMAScript 5 增加了数组检测的原生方法:

    Array.isArray(obj)
    

    函数

    虽然 typeof 运算符将函数特别对待了,但是使用 typeof 运算符在有些实现中不是函数的也会返回 'function',因此还是使用如下方法来判断函数:

    Object.prototype.toString.call(obj) === '[object Function]'
    

    正则表达式

    使用 typeof 运算符判断正则表达式,一般都会返回 'object',不过也有一些实现会返回 'function',所以,还是借用 Object.prototype.toString 方法来判断:

    Object.prototype.toString.call(obj) === '[object RegExp]'
    

    参考资料

  • 相关阅读:
    java学习--基础知识进阶第十一天--笔记
    java学习--基础知识进阶第十天--笔记
    java学习--基础知识进阶第十天--标准输入流 & 转换流 & 打印流、对象操作流 、Properties集合
    java学习--基础知识进阶第九天--笔记
    java学习--基础知识进阶第九天-- File类、字符流与字节流
    java学习--基础知识进阶第八天--笔记
    java学习--基础知识进阶第八天--异常体系&异常处理、Throwable常用方法&自定义异常、递归
    java学习--基础知识进阶第七天--笔记
    java学习--基础知识进阶第七天--HashSet集合、HashMap集合(集合遍历)
    java学习--基础知识进阶第六天--笔记
  • 原文地址:https://www.cnblogs.com/xyzhanjiang/p/4145951.html
Copyright © 2020-2023  润新知