用typeof 来检测数据类型

Javascript自带两套类型:基本数据类型(undefined,string,null,boolean,function,object)和对象类型。

但是如果尝试用typeof 来检测对象类型都一律返回"object"并不能加以区分

  1. typeof null // "object"
  2. typeof [] // "object"
  3. typeof document.childNodes //"object"
  4. typeof /\d/ //"object"
  5. typeof new Number() //"object"

用 constructor 属性来检测类型的构造函数

  1. [].constructor === Array //true
  2. document.childNodes === NodeList //true
  3. /\d/.constructor === RegExp //true
  4.  
  5. function isRegExp(obj) {
  6. return obj && typeof obj === "object" && obj.constructor === RegExp;
  7. } //检测正则表达式对象
  8.  
  9. function isNull(obj){
  10. return obj === null;
  11. }

用construct检测可以完成大多数的类型检测,null特殊直接比较。然而iframe中的数组类型确无法检测出正确类型,这是用construct检测的一个缺陷;同时在旧版本IE下DOM和BOM的construct是无法访问的

利用 Object.prototype.toString 来判断

  1. Object.prototype.toString.call([]) //"[object Array]"
  2. Object.prototype.toString.call(/\d/) // "[object RegExp]"
  3. Object.prototype.toString.call(1)//"[object Number]"

来看看jQuery源码中是如何使用toString方法的

  1. /*
  2. * jQuery JavaScript Library v1.11.2
  3. */
  4. var class2type = {}; //用来保存js数据类型
  5.  
  6. jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) {//构造class2type存储常用类型的映射关系,遍历基本类型并赋值,键值为 [object 类型]
  7. class2type[ "[object " + name + "]" ] = name.toLowerCase();
  8. });
  9.  
  10. type: function( obj ) {
  11. if ( obj == null ) {//首先如果是null则返回null字符串
  12. return obj + "";
  13. }
  14. //接着判断给定参数类型是否为object或者function,是的话在映射表中寻找 toString后的键值名称并返回,不是的话利用typeof就可以得到正确类型。
  15. return typeof obj === "object" || typeof obj === "function" ?
  16. class2type[ toString.call(obj) ] || "object" :
  17. typeof obj;
  18. },
  19. /****************************/
  20. jQuery.type(/\d/) //"regexp"
  21. jQuery.type(new Number()) //"number"

这里能够使用toString方法来检测是因为不同对象都会重新定义自己的toString方法

说说一些特殊类型的检测

上述调试是在IE8中进行的,因为undefined 在javascript中并不是关键字,在IE8以下(之后的版本不可以赋值)是可以赋值的,查看jQuery.type源码可知,对于undefined检测由是 typeof undefined完成的。jQuery.type并不能在旧的IE中检测出undefined的正确性。想要获得纯净的undefined可以使用void 0

另外,对于DOM,BOM对象在旧的IE中使用Objec.prototype.toString检测出来的值均为 “[object Object]”

但是在chrome下的结果却完全不同(chrome可以检测出真实类型)

了解一下jQuery检测特殊类型

  1. isWindow: function( obj ) {//ECMA规定window为全局对象global,且global.window === global
  2. return obj != null && obj == obj.window;
  3. },
  4.  
  5. isPlainObject: function( obj ) {
  6. var key;
  7. if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
  8. return false;
  9. }
  10.  
  11. try {//判断它最近的原形对象是否含有isPrototypeOf属性
  12. if ( obj.constructor &&
  13. !hasOwn.call(obj, "constructor") &&
  14. !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
  15. return false;
  16. }
  17. } catch ( e ) {
  18. return false;
  19. }
  20. if ( support.ownLast ) {
  21. for ( key in obj ) {
  22. return hasOwn.call( obj, key );
  23. }
  24. }

mass Framework相对jQuery中改善的地方

  1. var class2type = {//将可能出现的类型都映射在了class2type对象中,从而减少isXXX函数
  2. "[object HTMLDocument]": "Document",
  3. "[object HTMLCollection]": "NodeList",
  4. "[object StaticNodeList]": "NodeList",
  5. "[object DOMWindow]": "Window",
  6. "[object global]": "Window",
  7. "null": "Null",
  8. "NaN": "NaN",
  9. "undefined": "Undefined"
  10. };
  11.  
  12. type: function(obj, str) {
  13. var result = class2type[(obj == null || obj !== obj) ? obj : serialize.call(obj)] || obj.nodeName || "#"; //serialize == class2type.toString
  14. if (result.charAt(0) === "#") { //兼容旧式浏览器与处理个别情况,如window.opera
  15. //利用IE678 window == document为true,document == window竟然为false的神奇特性
  16. if (obj == obj.document && obj.document != obj) {//对DOM,BOM对象采用nodeType(单一)和item(节点集合)进行判断
  17. result = "Window"; //返回构造器名字
  18. } else if (obj.nodeType === 9) {
  19. result = "Document"; //返回构造器名字
  20. } else if (obj.callee) {
  21. result = "Arguments"; //返回构造器名字
  22. } else if (isFinite(obj.length) && obj.item) {
  23. result = "NodeList"; //处理节点集合
  24. } else {
  25. result = serialize.call(obj).slice(8, -1);
  26. }
  27. }
  28. if (str) {
  29. return str === result;
  30. }
  31. return result;
  32. }

类数组

类数组是一类特殊的数据类型存在,他们本身类似Array但是又不能使用Array的方法,他们有一个明显的特点就是含有length属性,而且键值是以整数有序的排列的。这样的数组可以通过 Array.slice() 这样的方法转换成真正的数组,从而使用Array提供的方法。

常见类数组:arguments,document.forms,document.getElementsByClassName(等一些列节点集合NodeList,HTMLCollection),或者是一些特殊对象,如下所示:

  1. var arrayLike={
  2. 0:"a",
  3. 1:"b",
  4. 2:"c",
  5. length:3
  6. }

通常情况下通过Array.slice.call既可以转换类数组,但是旧IE的HTMLCollection,NodeList不是Object的子类,不能使用该方法,这时候需要构建一个空数组,然后将遍历节点push就如空数组中,返回新生成的数组即可,同时要区别出window 和 string对象,因为这类的对象同样含有length>=0(length不可被修改),但是不是类数组。

jQuery如何处理类数组的

  1. makeArray: function( arr, results ) {
  2. var ret = results || [];
  3.  
  4. if ( arr != null ) {
  5. if ( isArraylike( Object(arr) ) ) {
  6. jQuery.merge( ret,
  7. typeof arr === "string" ?
  8. [ arr ] : arr
  9. ); //jQuery.merge 合并数组 ,若是字符串则封装成数组河滨,不是则世界合并
  10. } else {
  11. push.call( ret, arr );
  12. }
  13. }
  14.  
  15. return ret;
  16. }

Ext.js是如何处理类数组的

  1. toArray: function(iterable, start, end) {
  2. if (!iterable || !iterable.length) {
  3. return []; //非类数组类型直接返回[]
  4. }
  5. if (typeof iterable === 'string') {
  6. iterable = iterable.split(''); //分解字符串
  7. }
  8. if (supportsSliceOnNodeList) {
  9. return slice.call(iterable, start || 0, end || iterable.length); //对于NodeList支持
  10. }
  11. var array = [],
  12. i;
  13. start = start || 0;
  14. end = end ? ((end < 0) ? iterable.length + end : end) : iterable.length;
  15. for (i = start; i < end; i++) {
  16. array.push(iterable[i]);
  17. }
  18. return array;
  19. }

mass Framework.js是如何处理类数组的

  1. slice: W3C ? function(nodes, start, end) { //var W3C = DOC.dispatchEvent; IE9开始支持W3C的事件模型
  2. return factorys.slice.call(nodes, start, end);
  3. } : function(nodes, start, end) {
  4. var ret = [],
  5. n = nodes.length;
  6. if (end === void 0 || typeof end === "number" && isFinite(end)) {
  7. start = parseInt(start, 10) || 0;
  8. end = end == void 0 ? n : parseInt(end, 10);
  9. if (start < 0) {
  10. start += n;
  11. }
  12. if (end > n) {
  13. end = n;
  14. }
  15. if (end < 0) {
  16. end += n;
  17. }
  18. for (var i = start; i < end; ++i) {
  19. ret[i - start] = nodes[i];
  20. }
  21. }
  22. return ret;
  23. }

总结的JS数据类型判定(非常全面)的更多相关文章

  1. JavaScript大厦之地基:js数据类型

    一.数据和类型        俗话说物以类聚,人以群分:这里将人和物都按类别进行了区分.我们数据也一样,使用计算机我们能处理数值,也可以处理文本还可以处理图形.音频.视频等各种各样的数据,不同的数据有 ...

  2. 由js apply与call方法想到的js数据类型(原始类型和引用类型)

    原文地址:由js apply与call方法想到的js数据类型(原始类型和引用类型) js的call方法与apply方法的区别在于第二个参数的不同,他们都有2个参数,第一个为对象(即需要用对象a继承b, ...

  3. JavaScript学习10 JS数据类型、强制类型转换和对象属性

    JavaScript学习10 JS数据类型.强制类型转换和对象属性 JavaScript数据类型 JavaScript中有五种原始数据类型:Undefined.Null.Boolean.Number以 ...

  4. JS数据类型的理解(猜测)

    Js 数据类型 对于这个主题,首先来看几个问题,如果你对这几个问题很清楚的话,那就请直接跳过吧,不用接着往下看了,如果不清楚,建议你还是看看. 1)如果判断函数?function 和object的联系 ...

  5. web开发与设计--js数据类型,js运营商

    1. js数据类型划分:号码值类型,布尔,串 由typeof能够看到什么类型的数据被详述. 举例: <span style="font-family:Microsoft YaHei;f ...

  6. [妙味JS基础]第四课:JS数据类型、类型转换

    知识点总结 JS数据类型:number数字(NaN).string字符串.boolean布尔值.函数类型.object对象(obj.[].{}.null).undefined未定义 typeof 用来 ...

  7. JS 数据类型、赋值、深拷贝和浅拷贝

    js 数据类型 六种 基本数据类型: Boolean. 布尔值,true 和 false. null. 一个表明 null 值的特殊关键字. JavaScript 是大小写敏感的,因此 null 与 ...

  8. 1. js数据类型_对象_函数_内存

    1. js数据类型有哪些? 基本(值)类型 Number ---- 任意数值 String ---- 任意字符串 Boolean ---- true/false undefined ---- unde ...

  9. js数据类型隐式转换问题

    js数据类型隐式转换 ![] == false //true 空数组和基本类型转换,会先[].toString() 再继续比较 ![] == [] //true ![] //false [] == [ ...

随机推荐

  1. 将String转化成Stream,将Stream转换成String

    using System;using System.IO;using System.Text;namespace CSharpConvertString2Stream{     class Progr ...

  2. SQL SERVER 2014 Agent服务异常停止案例

    生产环境一数据库服务器(SQL Server 2014)的Agent服务突然停掉了,检查了错误日志,发现在"SQL Server Agent"里面没有"SQLServer ...

  3. Linux启动报错missing operating system

    用UltraISO制作了一个Red Hat Enterprise Linux Server release 5.7系统的U盘启动盘,然后在一台PC上安装,由于安装过程中在干别的事情,有些选项没有细看. ...

  4. FindBugs 入门——帮你减少代码中的bug数

    FindBugs 入门 FindBugs 作用 开发人员在开发了一部分代码后,可以使用FindBugs进行代码缺陷的检查.提高代码的质量,同时也可以减少测试人员给你报的bug数. 代码缺陷分类 根据缺 ...

  5. Oracle转移数据表空间存储位置

    问题描述:Oracle表空间创建到了C盘,发现C盘的空间不够,现在将表空间的文件转移到D盘下. 操作方法: 1. 先登录sqlplus,登录用户.在cmd中输入:sqlplus /nologSQL&g ...

  6. SQL Server 2008 R2——查找最小nIndex,nIndex存在而nIndex+1不存在 求最小连续数组中的最大值

    =================================版权声明================================= 版权声明:原创文章 谢绝转载  请通过右侧公告中的“联系邮 ...

  7. 从微软下载安装Windows10

    如果你需要安装或重新安装 Windows 10,可以通过此页面上的工具,使用 U 盘或 DVD 创建你自己的安装介质. 开始之前 确保你具有以下内容: Internet 连接(可能产生 Interne ...

  8. 编译软件基础知识(2/2) via LinuxSir

    首先说下/etc/ld.so.conf: 这个文件记录了编译时使用的动态链接库的路径. 默认情况下,编译器只会使用/lib和/usr/lib这两个目录下的库文件 如果你安装了某些库,比如在安装gtk+ ...

  9. oracle 倒库后insert id冲突的问题

    错误为:ORA-00001: unique constraint violated 把test库的数据导入到另一个库后,忘记修改自增id sequence的nextval了,因此,当前的数据库中数据和 ...

  10. sass入门

    SASS是一种CSS的开发工具,提供了许多便利的写法,大大节省了设计者的时间,使得CSS的开发,变得简单和可维护. SASS 官网介绍: sass is the most mature(成熟的),st ...