目录
JavaScript 是弱类型语言,对类型没有严格限制,但在程序中经常需要对类型进行检测和转换,下面是一些类型转换和检测的技巧
1、使用 typeof 检测类型
typeof 运算符专门用来检测值的类型,特别对于原始值有效,而对于对象类型的数据,如数组、对象等,返回的值都是字符串 "object"。一下代码显示使用 typeof 检测数据类型的方法。
alert(typeof 1); //返回字符串"number"
alert(typeof "a"); //返回字符串"string"
alert(typeof true); //返回字符串"boolean"
alert(typeof {}); //返回字符串"object"
alert(typeof []); //返回字符串"object"
alert(typeof function(){}); //返回字符串"function"
alert(typeof undefined); //返回字符串"undefined"
alert(typeof null); //返回字符串"object"
alert(typeof NaN); //返回字符串"number"
由于 JavaScript 把 null 归为 object 数据类型,用户可以定义一个简单数据类型的检测方法:
function type(o){
return (o === null) ? null : (typeof 0);
//如果是null,则返回字符串"null",否则返回(typeof 0)表达式的值
}
以上代码可防止因为null值而影响基本数据的类型检测。
2、使用 constructor 检测类型
对于对象、数组等复杂数据,可以使用 Object 对象的 constructor 属性进行检测。constructor 表示构造器,该属性值引用的是构造当前对象的函数。以下代码可以检测对象直接量和数组直接量的类型。
var o = {};
var a = [];
alert(o.constructor == Object); //返回true
alert(a.constructor == Array); //返回true
通过以上方法可以准确判断复杂数据是对象还是数组。如果结合 typeof 运算符和 constructor 属性,用户基本能够完成数据类型的检测,如下表所示列举了不同类型数据的检测结果。测试代码如下:
var value = 1; //输入不同类型的值(第1列)
alert(typeof value); //返回typeof运算符返回的字符串(第2列)
alert(value.constructor);//返回 constructor属性返回的对象(第3列)
值(value) | typeof value(表达式返回值) | value.constructor(构造函数的属性值) |
var value = 1 | "number" | Number |
var value = "a" | "string" | String |
var value = true | "boolean" | Boolean |
var value = {} | "object" | Object |
var value = new Object | "object" | Object |
var value = [] | "object" | Array |
var value = new Array() | "object" | Array |
var value = function(){} | "function" | Function |
function className(){} var value = new className(); | "object" | className |
使用 constructor 属性可以检测绝大部分数据的类型,但对于 undefined 和 null 特殊值,就不能够使用 constructor 属性,否则会抛出异常。这时可以先把值转换为布尔值,如果为 true,则说明是存在值的,然后再调用 constructor 属性。
var value = undefined;
alert(typeof value); //返回字符中"undefined"
alert(value && value.conatructor); //返回undefined
var value = null;
alert(typeof value); //返回字符串"object"
alert(value && value.conatructor); //返回null
另外,对于数值直接量也不能直接使用 constructor 属性。例如,以下代码将会提示语法错误。
alert{10.conatruotor}; //但是如果加上一个小括号,则可以检测:
alert{(10).constructor)}; //这是因为小括号运算符能够把数值转换为对象。
3、类型检测方法 toString()
不同类型对象的 toString() 方法返回值有所不同,但由 Object 对象定义的 toString() 方法返回的字符串形式总是:
[object class]
其中 object 表示对象的通用类型,class 表示对象的内部类型,内部类型的名称与该对象的构造函数名对应。例如,Array 对象的 class为 "Array",Function 对象的 class 为 "Function",Date 对象的 class 为 "Date",内部Math对象的 class 为 "Math",所有 Error 对象(包括各种 Error 子类的实例)的 class 为 "Error"。
alert(Object.prototype.toString.apply('')) // [object String]
alert(Object.prototype.toString.apply(1)) // [object Number]
alert(Object.prototype.toString.apply(true)) // [object Boolean]
alert(Object.prototype.toString.apply(Symbol())) // [object Symbol]
alert(Object.prototype.toString.apply(undefined)) // [object Undefined]
alert(Object.prototype.toString.apply(null)) // [object Null]
alert(Object.prototype.toString.apply(new Function())) // [object Function]
alert(Object.prototype.toString.apply(new Date())) // [object Date]
alert(Object.prototype.toString.apply([])) // [object Array]
alert(Object.prototype.toString.apply(new RegExp())) // [object RegExp]
alert(Object.prototype.toString.apply(new Error())) // [object Error]
alert(Object.prototype.toString.apply(document)) // [object HTMLDocument]
alert(Object.prototype.toString.apply(window)) // [object global] window 是全局对象 global 的引用
class 值提供的信息与对象的 constructor 属性值相似,但是class值是以字符串的形式提供这些信息的,这在特定的环境中是非常有用的。如果使用 typeof 运算符来检测,则所有对象的 class 值都为 “Object” 或 “Function” 。所以不能够提供有效信息。
但是,要获取对象的 class 值的唯一方法是必须调用 Object 的原型方法 toString(),因为很多类型对象都会重置 Object 的toString()方法,所以不能直接调用对象的 toString() 方法。
调用 Object 的 toString()原型方法,可以通过调用 Object.prototype.toString 对象的默认 toString() 函数,再调用该函数的 apply() 方法在想要检测的对象上执行即可。