zoukankan      html  css  js  c++  java
  • 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]'
    

    参考资料

  • 相关阅读:
    D. Babaei and Birthday Cake--- Codeforces Round #343 (Div. 2)
    Vijos P1389婚礼上的小杉
    AIM Tech Round (Div. 2) C. Graph and String
    HDU 5627Clarke and MST
    bzoj 3332 旧试题
    codeforces 842C Ilya And The Tree
    codesforces 671D Roads in Yusland
    Travelling
    codeforces 606C Sorting Railway Cars
    codeforces 651C Watchmen
  • 原文地址:https://www.cnblogs.com/xyzhanjiang/p/4145951.html
Copyright © 2011-2022 走看看