typeof
用法示例
var arr = [];
typeof arr; //'object'
typeof(arr); //'object'
typeof
实际上是一个一元运算符,因此可以用上述代码所示的两种用法。
typeof
所支持的数据类型
从上表可以看出,typeof
支持的数据类型还是比较齐全的,除了俩比较特殊以外:
- 对
Null
使用typeof
返回object
,这跟我们的认知还是有一定差距的,这是javascript的一个设计上的bug,ECMAScript 6
中有提议修改此bug,但已经被否决了;不过只要加个逻辑非!
运算符,就能把Null
这种情况给排除了。 - 除了
function
以外,其它具体的对象类型都无法判断出来。
typeof
浏览器兼容性注意点
对正则表达式字面量的类型判断在某些浏览器中不符合标准:
typeof /s/ === 'function'; // Chrome 1-12 , 不符合 ECMAScript 5.1
typeof /s/ === 'object'; // Firefox 5+ , 符合 ECMAScript 5.1
IE 宿主对象是对象而不是函数
在 IE 6, 7 和 8 中,大多数的宿主对象是对象,而不是函数,例如:
typeof alert === 'object'
instanceof
用法示例
// 定义构造函数
function C(){}
function D(){}
var o = new C();
// true,因为 Object.getPrototypeOf(o) === C.prototype
o instanceof C;
// false,因为 D.prototype不在o的原型链上
o instanceof D;
o instanceof Object; // true,因为Object.prototype.isPrototypeOf(o)返回true
instanceof
是一个二元运算符。
instanceof
总结
- javascript中的原生对象以及用户的自定义对象基本上都能利用
instanceof
识别出来,除了Null和Undefined。 -
instanceof
无法区分开同一原型继承链:
function A(){
//...
}
function B(){
//...
}
function C(){
//...
}
var a = new A();
B.prototype = a;
var b = new B();
C.prototype = b;
var c = new C();
c instanceof A; //true
c instanceof B; //true
c instanceof C; //true
Object.prototype.toString.call
用法示例
function type(obj) {
return Object.prototype.toString.call(obj).slice(8, -1);
}
type(1); //"Number"
type("1"); //"String"
type(true); //"Boolean"
type(undefined); //"Undefined"
type(null); //"Null"
type({}); //"Object"
type([]); //"Array"
type(new Date); //"Date"
type(/\d/); //"RegExp"
type(function() {}); //"Function"
function Point(x, y) {
//
}
type(new Point(1, 2)); //"Object"
用法解析
从以上用法示例可以看出,这个基于Object.prototype.toString.call
封装好的函数用法跟typeof
非常相似,但是在支持的数据类型上比typeof
强多了,所有的javascript原生数据类型都能判断出来。遗憾的是,Object.prototype.toString.call
也不是万能的方案:无法识别自定义的对象类型。Object.prototype.toString.call
实际上是返回这样形式的值:
Object.prototype.toString.call(1); //'[object Number]'
Object.prototype.toString.call('1'); //'[object String]'
因此只要用slice方法把数据类型“切”出来就成了。
constructor(构造函数)
用法示例
/*
* 获取对象构造函数名称
*/
function getConstructorName(obj){
return obj && obj.constructor && obj.constructor.toString().match(/function\s*([^(]*)/)[1]; //利用obj && obj.constructor来判断null和undefined
}
用法解析
这是一种非常巧妙的判断数据类型的方法——利用构造函数判断数据类型,这是基于javascript的特性/规范:
- 对象的构造函数名就是该数据类型。
- 除Null和Undefined外,所有的数据类型都是/可以转化为对象,而如果是对象,就肯定有构造函数。
特性
- 因为Null和Undefined没有构造函数,因此不能用此方法来判断。
- 由于同一条原型继承链上的各个对象的构造函数都不一样,因此,此方法可以区分开继承链上的各个自定义数据类型。
function A(){
//...
}
function B(){
//...
}
function C(){
//...
}
var a = new A();
B.prototype = a;
var b = new B();
C.prototype = b;
var c = new C();
getConstructorName(a); //A
getConstructorName(b); //B
getConstructorName(c); //C
总结
以上这四种方法都有不同程度的缺陷,如果从实用性的角度来考虑,可以综合一下:
function type(obj) {console.dir(obj);
if(!obj) {
return Object.prototype.toString.call(obj).slice(8, -1);
}
return obj.constructor.toString().match(/function\s*([^(]*)/)[1];
}
var t = type(1) // t==="number"
var t = type(new Number(1)) // t==="number"
var t = type("abc") // t==="string"
var t = type(new String("abc")) // t==="string"
var t = type(true) // t==="boolean"
var t = type(undefined) // t==="undefined"
var t = type(null) // t==="null"
var t = type({}) // t==="object"
var t = type([]) // t==="array"
var t = type(new Date) // t==="date"
var t = type(/\d/) // t==="regexp"
var t = type(function(){}) // t==="function"
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。