javascript类型检测主要包括下面几个方法:
typeof
instanceof
Object.prototype.toString
constructor
duck type
一、typeof方法
typeof可以检测给定变量的数据类型,对一个值使用typeof操作符可能返回下列某个字符串:
“undefined” 如果这个值未定义
“boolean” 如果这个值是布尔值
"string" 如果这个值是字符串
“number” 如果这个值是数值
“object” 如果这个值是对象或null
“function” 如果这个值是函数
例如:
function a(){}
typeof 100;//number
typeof true;//boolean
typeof "str";//string
typeof undefined;//undefined
typeof null;//object
typeof NaN;//number
typeof Function;//function
typeof Object;//function
typeof new Object();//object
typeof [1,2];//object
typeof a;//function
null值表示一个空对象指针,所以检测typeof null 的值会返回“object”
二、instanceof 方法
语法:result=variable instanceof constructor
如果变量是给定引用类型的实例,那么instanceof 操作符就会返回true
function Person(){}
function Student(){}
Student.prototype=new Person();
Student.prototype.constructor=Student;
var bosn=new Student();
var one=new Person();
bosn instanceof Student;//true
one instanceof Person;//true
one instanceof Student;//false
bosn instanceof Person;//true
var colors=["red","blue","green"];
console.log(colors instanceof Array);//true
var pattern=/[ac]ont/gi;
console.log(pattern instanceof RegExp);//true
var date=new Date();
console.log(date instanceof Date);//true
所有引用类型的值都是Object的实例
三、Object.prototype.toString 方法
Object.prototype.toString.apply([]); === “[object Array]”;
Object.prototype.toString.apply(function(){}); === “[object Function]”;
Object.prototype.toString.apply(null); === “[object Null]”
Object.prototype.toString.apply(undefined); === “[object Undefined]”
Object.prototype.toString.apply(new Date());//[object Date]
Object.prototype.toString.apply(new String("str"));//[object String]
Object.prototype.toString.apply("str");//[object String]
Object.prototype.toString.apply(123);//[object Number]
Object.prototype.toString.call 与 Object.prototype.toString.apply 是一样的。
判断原生引用类型:
函数类型
Function fn(){console.log(“test”);}
Object.prototype.toString.call(fn);//”[object Function]”
日期类型
var date = new Date(); Object.prototype.toString.call(date);//”[object Date]”
数组类型
var arr = [1,2,3]; Object.prototype.toString.call(arr);//”[object Array]”
正则表达式
var reg = /[hbc]at/gi; Object.prototype.toString.call(reg);//”[object Array]”
自定义类型
function Person(name, age) {
this.name = name;
this.age = age;
}
var person = new Person("Rose", 18);
Object.prototype.toString.call(person); //”[object Object]”
判断原生JSON对象:
var isNativeJSON = window.JSON && Object.prototype.toString.call(JSON); console.log(isNativeJSON);//输出结果为”[object JSON]”说明JSON是原生的,否则不是;
四、construct 方法
var test=new Array();
console.log(test.constructor==Array);//true
function A(){};
var a1=new A();
console.log(a1.constructor==A);//true
console.log(A.prototype.constructor==A);//true
实例:
// 构造函数
function Foo(y) {
// 构造函数将会以特定模式创建对象:被创建的对象都会有"y"属性
this.y = y;
}
// "Foo.prototype"存放了新建对象的原型引用
// 所以我们可以将之用于定义继承和共享属性或方法
// 所以,和上例一样,我们有了如下代码:
// 继承属性"x"
Foo.prototype.x = 10;
// 继承方法"calculate"
Foo.prototype.calculate = function (z) {
return this.x + this.y + z;
};
// 使用foo模式创建 "b" and "c"
var b = new Foo(20);
var c = new Foo(30);
// 调用继承的方法
b.calculate(30); // 60
c.calculate(40); // 80
// 让我们看看是否使用了预期的属性
console.log(
b.__proto__ === Foo.prototype, // true
c.__proto__ === Foo.prototype, // true
// "Foo.prototype"自动创建了一个特殊的属性"constructor"
// 指向a的构造函数本身
// 实例"b"和"c"可以通过授权找到它并用以检测自己的构造函数
b.constructor === Foo, // true
c.constructor === Foo, // true
Foo.prototype.constructor === Foo // true
b.calculate === b.__proto__.calculate, // true
b.__proto__.calculate === Foo.prototype.calculate // true
);
五、duck type 方法
在程序设计中,鸭子类型(英语:duck typing)是动态类型的一种风格。在这种风格中,一个对象有效的语义,不是由继承自特定的类或实现特定的接口,而是由当前方法和属性的集合决定。这个概念的名字来源于由James Whitcomb Riley提出的鸭子测试,“鸭子测试”可以这样表述:
“当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。”
在鸭子类型中,关注的不是对象的类型本身,而是它是如何使用的。
六、总结
typeof 适合基本类型及function检测,遇到null失效。
Object.prototype.toString 通过{}.toString拿到,适合内置对象和基元类型,遇到null和undefined失效(IE678等返回[object Object])。
instanceof 适合自定义对象,也可以用来检测原生对象,在不同iframe和window间检测时失效。