JavaScript数据类型检测
数据类型概述
JavaScript的数据类型不像Java等语言那样清晰,或许这是JavaScript的变量是松散类型的原因。概括地讲,JavaScript变量的数据类型包括:
- Undefined
- Boolean
- Number
- String
- Object
- Function
其中,Boolean/Number/String为基本类型,Object为引用类型,Function为函数,Undefined为JavaScript作为松散类型所特有的数据类型,在后文中会专门介绍。
注:
在【JavaScript高级程序设计】中,还定义了专门的Null类型,表示字面值为null
的变量;并将Undefined类型也作为基本数据类型的一种。
typeof
操作符
变量或字面值的数据类型可以通过一元操作符typeof
来粗略的检测,它返回一个字符串,表示待检测变量或字面值的数据类型,下面展示了一组类型检测的示例:
typeof 1 // ="number"
typeof NaN // ="number"
typeof Number.MIN_VALUE // ="number"
typeof Infinity // ="number"
typeof "123" // ="string"
typeof true // ="boolean"
typeof window // ="object"
typeof document // ="object"
typeof Array // ="object"
typeof null // ="object"
typeof function {} // ="function"
typeof eval // ="function"
typeof Date // ="function"
typeof sss // ="undefined"
typeof undefined // ="undefined
特别的,null
认为是一个空的对象引用,因此typeof null = "object"
。
注:typeof
检测函数时的局限性
在Safari 5及之前版本和Chrome 7及之前版本中,使用typeof
操作符检测正则表达式时,也会返回"undefined"
。这是由于在ECMA-262规范中,规定任何在内部实现[[call]]方法的对象在应用typeof
时都应返回"function"
,而上述浏览器的正则表达式中实现了该方法,从而引发这个问题。在IE和Firefox中则不存在这个问题,对正则表达式应用typeof
时返回"object"
。
基本数据类型
基本数据类型(Boolean/Number/String)可以通过typeof
操作符来检测,如下所示:
typeof your-variable == 'boolean' // 判断是否为Boolean类型
typeof your-variable == 'number' // 判断是否为Number类型
typeof your-variable == 'string' // 判断是否为String类型
Undefined类型
undefined
undefined
是一个特殊的值。声明一个未初始化的变量,其默认值即为undefined
,如下面的示例所示。需要注意的是,typeof message
得到的是一个字符串"undefined"
,表示这个变量是Undefined类型。var message; // =undefined alert(message == undefined); // =true
注:
undefined
派生自null
,因此,他们进行比较的时候认为是相等的,即:alert(undefined == null); // =true
typeof your-variable == "undefined"
有两种类型的变量在执行
typeof
检测时为"undefined"
:已声明但未初始化或直接赋值
undefined
的变量未声明的变量
对未声明的变量,只能执行一种操作,即通过
typeof
检测类型,否则,任何显式的调用都将导致ReferenceError
错误。
判断变量是否声明或是否初始化的方法
由前文可以看出,无法通过
typeof your-variable == "undefined"
判断一个变量是未声明或还是未初始化。对于全局变量,可通过下面的方法判断该变量有没有声明和初始化:"your-variable" in window // 判断变量是否已声明 "your-variable" in window && typeof your-variable == "undefined" // 判断变量是否未初始化
instanceof
操作符
instanceof
操作符用于引用类型的检测,用来判断一个引用类型是什么类型的对象。如下所示,判断变量colors
是否为Array
类型:
var colors = new Array('red', 'green', 'blue');
alert(colors intanceof Array); // =true
此外,对于原生的函数也可以通过instanceof
检测,如:
alert(eval instanceof Function); // =true
alert(Function instanceof Object); // =true
注:instanceof
的局限性:
当存在多个全局作用域(如一个页面包含多个frame)时,instanceof
检测引用类型时会存在问题。因为Array
是window的属性,如果通过your-variable instanceof Array
检测是不是Array
类型,不仅要求your-variable
不仅是个数组,还必须与初始化它的语句在同一个全局作用域下。
引用类型
引用类型可以使用typeof
和instanceof
操作符共同来检测,如下所示。
typeof your-variable == "object" && your-variable == null // 判断是否为null
typeof your-variable == "object" && your-variable instanceof Object // 判断是否为Object类型
typeof your-variable == "object" && your-variable instanceof Array // 判断是否为Array类型
引用类型与函数类型的安全检测
如前文所述,typeof
和instanceof
操作符在检测引用类型和函数类型时存在局限性,并不十分可靠。因此,这里介绍更安全的类型检测方法。
由于在任何值上调用Object原生的toString()方法,都会返回[object NativeConstructorName]
格式的字符串,其中,NativeConstructorName
由类的[[class]]
属性指定,因此,可通过该方法对引用类型和函数类型做更可靠的检测,如下所示:
typeof your-variable != 'undefined' && Object.prototype.toString.call(your-variable) == '[object Array]' // 判断是否为Array类型
typeof your-variable != 'undefined' && Object.prototype.toString.call(your-variable) == '[object RegExp]' // 判断是否为RegRex类型
typeof your-variable != 'undefined' && Object.prototype.toString.call(your-variable) == '[object Function]' // 判断是否为原生函数
注:
该方法不能检测非原生构造函数的构造函数名,开发人员定义的任何构造函数都将返回[object Object]
。