Zydecx's Site

Debug code, debug life, debug today!

JavaScript数据类型检测

Time: , by zydecx

数据类型概述

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不仅是个数组,还必须与初始化它的语句在同一个全局作用域下。

引用类型

引用类型可以使用typeofinstanceof操作符共同来检测,如下所示。

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类型

引用类型与函数类型的安全检测

如前文所述,typeofinstanceof操作符在检测引用类型和函数类型时存在局限性,并不十分可靠。因此,这里介绍更安全的类型检测方法。

由于在任何值上调用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]


This is a magic phrase. You CANNOT see it(I'll really FULE you if you do that), but it does work. Why? You may feel confused. OK, at least it doesn't afftect your experience and it works. That is what we call MAGICE!