JavaScript中怎么样判断一个对象到底是什么类型呢?
先给出jQuery的最终实现,之后分析
jQuery源码
代码语言:javascript复制 1 var class2type = {};
2 jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
3 function( i, name ) {
4 class2type[ "[object " + name + "]" ] = name.toLowerCase();
5 } );
6 function type( obj ) {
7 if ( obj == null ) {
8 return obj + "";
9 }
10 return typeof obj === "object" || typeof obj === "function" ?
11 class2type[ toString.call(obj) ] || "object" :
12 typeof obj;
13 }jQuery的API中有以下几个基于type的方法:
isFunction(obj)
实现:return jQuery.type(obj) === "array";isArray(obj)
实现:Array.isArray || function( obj ) {
return jQuery.type(obj) === "array";也可以这样实现:
代码语言:javascript复制 1 function type(obj){
2 return Object.prototype.toString.call(obj).slice(8,-1);
3 }分析
所有的引用均来自于 JavaScript | MDN
获得对象类型的方法有四种:
1. typeof
代码语言:javascript复制typeof operandoperand is an expression representing the object or primitive whose type is to be returned.
operand是一个表示object或原始数据类型的表达式
在 JavaScript 最初的实现中,JavaScript 中的值是由一个表示类型的标签和实际数据值表示的。由于 null 代表的是空指针(大多数平台下值为0x00),因此,null的类型标签也成为了0,typeof null就错误的返回了"object".
2. obj instanceof constructor
The instanceof operator tests whether an object has in its prototype chain the prototype property of a constructor.
instanceof运算符用来判断某个构造函数的prototype属性所指向的对象是否存在于另外一个要检测对象的原型链上。
需要注意的是,如果表达式 obj instanceof Foo 返回true,则并不意味着该表达式会永远返回ture,因为Foo.prototype属性的值有可能会改变,改变之后的值很有可能不存在于obj的原型链上,这时原表达式的值就会成为false。另外一种情况下,原表达式的值也会改变,就是改变对象obj的原型链的情况,虽然在目前的ES规范中,我们只能读取对象的原型而不能改变它,但借助于非标准的__proto__魔法属性,是可以实现的。比如执行obj.__proto__ = {}之后,obj instanceof Foo就会返回false了。
还有个问题是多frame或多window之间的交互
在浏览器中,我们的脚本可能需要在多个窗口之间进行交互。多个窗口意味着多个全局环境,不同的全局环境拥有不同的全局对象,从而拥有不同的内置类型构造函数。这可能会引发一些问题。比如,表达式 [] instanceof window.frames[0].Array 会返回false,因为 Array.prototype !== window.frames[0].Array.prototype,因此你必须使用 Array.isArray(myObj) 或者Object.prototype.toString.call(myObj) === "[object Array]"来判断myObj是否是数组。
3. Object.prototype.toString()
Every object has a toString() method that is automatically called when the object is to be represented as a text value or when an object is referred to in a manner in which a string is expected. By default, thetoString() method is inherited by every object descended from Object. If this method is not overridden in a custom object, toString() returns "[object type]", where type is the object type.
如果这个方法没有被这个对象自身或者更接近的上层原型上的同名方法覆盖(遮蔽),则调用该对象的toString()方法时会返回"[object type]"。