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类型
undefinedundefined是一个特殊的值。声明一个未初始化的变量,其默认值即为undefined,如下面的示例所示。需要注意的是,typeof message得到的是一个字符串"undefined",表示这个变量是Undefined类型。var message; // =undefined alert(message == undefined); // =true注:
undefined派生自null,因此,他们进行比较的时候认为是相等的,即:alert(undefined == null); // =truetypeof 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]。