老话题了,各种方案和相关讨论都不少,简单总结下: 悠久的typeof JavaScript里只有五种基本数据类型:number, string, boolean, null, undefined. 其它的都是复合数据类型object. 值和数据类型是两码事。比如:null是null类型的唯一值,undefined是undefined类型的唯一值,就如true和false是boolean类型的唯两值一样。 可以用typeof检测出以下6种数据类型:number, string, boolean, undefined, object, function. 注意:typeof null == “object”. null类型的唯一值null的类型是object类型。(很拗口,但事实就是这样) 因此,对于五种基本数据类型来说,用下面的代码就可以检测出来: // 获取变量o的数据类型 function type(o) { return (o === null) ? 'null' : typeof(o); } instanceof的作用typeof只能检测基本数据类型,对于复合数据类型,除了function,都通通返回'object'. instanceof可以检测某个对象是不是另一个对象的实例,注意instanceof的右操作数必须为对象: alert(1 instanceof Number); // false alert({} instanceof Object); // true instanceof还可以检测父类型: function Animal() {}; function Pig() {}; Pig.prototype = new Animal(); alert(new Pig() instanceof Animal); // true 可以看出,instanceof不适合用来检测一个对象本身的类型。 救命稻草:constructor JavaScript里的所有对象都拥有一个constructor属性,但JavaScript里并非一切都是对象: alert(1.constructor); // 报错 var o = 1; alert(o.constructor); // Number o = null; // or undefined alert(o.constructor); // 报错 alert({}.constructor); // Object alert(true.constructor); // Boolean 可以看出,null和undefined没有constructor,number和string数据类型的字面量,也没有constructor,但number和string数据类型的变量有constructor(在寻找constructor属性时,会自动转换成Number或String对象)。 下面是Johg Resig《Pro JavaScript Techniques》书中的一张表: 这样,对于复合数据类型,我们可以采用下面的方法检测: ... isArray: function(arr) { return !!arr && arr.constructor == Array; } ... jQuery 1.2中采用的就是上面的代码。 一切看起来很完美,然而不安分的iframe总喜欢来捣点鬼: // 请在非ie浏览器中运行 var iframe = document.createElement('iframe'); document.body.appendChild(iframe); var xArray = window.frames[window.frames.length-1].Array; var arr = new xArray(1, 2, 3); // [1,2,3] alert(arr.constructor === Array); // false 原因很简单:不同frame中的Array拥有不同的constructor. 鸭子也上场:Duck Typing 在犀牛书里,提到一句老话:“如果走路像鸭子,叫声也像鸭子,那它就是一个鸭子!” 换言之,对于Array来说,如果一个对象有splice和join属性,那它就是Array. 这就是Duck Typing: function isArray(o) { return o != null && typeof o === ‘object’ && 'splice' in o && 'join' in o; } 上面是Prototype 1.6中的代码。 显然,鸭子检测很容易误把自造的天鹅也当成鸭: alert(isArray({'splice': '', 'join': ''})); // true 鸭子检测的一个用途是,可以用来检测类似对象,比如类数组: function isArrayLike(x) { if (x instanceof Array) return true; // Real arrays are array-like if (!('length' in x)) return false; // Arrays must have a length property if (typeof x.length != 'number') return false; // Length must be a number if (x.length < 0) return false; // and nonnegative if (x.length > 0) { // If the array is nonempty, it must at a minimum // have a property defined whose name is the number length-1 if (!((x.length - 1) in x)) return false; } return true; } 上面的代码摘自犀牛书。 时间太晚,今天就写到这。留两个问题:
晚安,朋友们! [ 本帖最后由 lifesinger 于 2009-2-5 14:13 编辑 ] |
引用 报告 回复 |
lifesinger
爬虫
UID 91925 精华 0 积分 62 帖子 13 威望 35 阅读权限 20 注册 2008-10-9 状态 在线 |
|