浅谈判断变量类型

242 阅读3分钟

「这是我参与11月更文挑战的第5天,活动详情查看:2021最后一次更文挑战」。


前言

在项目中,我们经常需要去判断一个变量属于什么类型,因为js的语法糖太多了,判断的方式可谓也是五花八门,这里分享一下

各类型typeof的值

类型结果
Undefined"undefined"
Null"null"
Boolean"boolean"
Number"number"
String"string"
Symbol"symbol"
函数对象"function"
任何其他对象"object"

判断变量是否为数字

值得注意的是

typeof null === 'object'

在 JavaScript 最初的实现中,JavaScript 中的值是由一个表示类型的标签和实际数据值表示的。对象的类型标签是0。因为 null 代表的是空指针(大多数平台下值为0x00),因而,null的类型标签也成为了0,typeof null就错误的返回了"object".

需要做的

1.判断是否是Number类型 2.判断是否溢出 3.判断是否是整数

三步走

  1. 判断是否是Number类型

    判断是否为Number类型很容易想到用 typeof(value),但是需要注意的是 typeof(NaN) 的返回值也是'number',所以不难写出:

     function isNumber(value) {
     	return value === value && typeof(value) === 'number';
     }
    
  2. 判断是否溢出

    在JS中有 Infinity 表示正数的无穷大,而又 -Infinity 表示负数的无穷小,而 isFinite(value) 可以正确的判断数字是否在有效范围之内,即它会滤过NaN和Infinity两类值

     isFinite(value)  // 排除NaN、Infinity 和 -Infinity
    
  3. 判断是否是整数

    有前面两个步骤作为铺垫之后,我们就可以安心的判断该变量是不是整数了

    判断是否为整数方法很多,在此我举例几个

     Math.round(value) === value  // 四舍五入取整
     Math.ceil(value) === value  // 向上取整
     Math.floor(value) === value  // 向下取整
    

最后整理一下

由上面的三步走归纳一下 可以得出:

Number.isInteger = Number.isInteger || function(value) {
	return typeof(value) === 'number' &&
		   isFinite(value) &&
		   Math.round(value) === value;
}

说在最后

有的同学可能会说:判断是否是整数直接用 parseInt(value,10) === value 不就可以了?很遗憾地告诉你,不可以!

parseInt(value,10) 首先会将value转化为字符串,然后再转化成整数,也就是说:

parseInt('123',10)  // 123
parseInt('123abc',10)  // 123
parseInt(123456789123456789123,10)  // 123456789123456800000

判断一个变量是否为数组

通常我们首先想到的是用 instanceof 去判断一个变量是否为数组

var a = [1,2,3]

a instanceof Array; //true

但是这种判断方式在跨域传值时就不管用了,比如现在父页面有一个iframe嵌套着一个子页面。在子页面中声明了一个变量a,并将其赋值给父页面的一个变量,这时用instanceof判断该变量是否为Array时,就会返回false

原因:Array是引用型数据,在传递过程中,传递的是引用的地址。而每个页面的Array原生对象所引用的地址是不一样的。所以当把子页面的Array对象传递到父页面进行判断时,它们肯定是不相等的。

正确的打开方式
Object.prototype.toString.call(array) === '[object Array]'

或者使用ES5标准中Array类新增的静态方法isArray()

Array.isArray(array)