JavaScript数据类型判定的总结笔记


Posted in Javascript onJuly 31, 2015

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

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

typeof null // "object"
typeof []  // "object"
typeof document.childNodes //"object"
typeof /\d/ //"object"
typeof new Number() //"object"

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

[].constructor === Array  //true
document.childNodes === NodeList  //true
/\d/.constructor === RegExp   //true
 
function isRegExp(obj) {
  return obj && typeof obj === "object" && obj.constructor === RegExp;
} //检测正则表达式对象
 
function isNull(obj){
  return obj === null;
}

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

利用 Object.prototype.toString 来判断

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

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

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

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

说说一些特殊类型的检测

JavaScript数据类型判定的总结笔记

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

JavaScript数据类型判定的总结笔记

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

JavaScript数据类型判定的总结笔记

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

JavaScript数据类型判定的总结笔记

了解一下jQuery检测特殊类型

isWindow: function( obj ) {//ECMA规定window为全局对象global,且global.window === global
 return obj != null && obj == obj.window;
},
isPlainObject: function( obj ) {
 var key;
 if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) {
  return false;
 }
 try {//判断它最近的原形对象是否含有isPrototypeOf属性
  if ( obj.constructor &&
   !hasOwn.call(obj, "constructor") &&
   !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) {
   return false;
  }
 } catch ( e ) {
  return false;
 }
 if ( support.ownLast ) {
  for ( key in obj ) {
   return hasOwn.call( obj, key );
  }
 }

mass Framework相对jQuery中改善的地方

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

类数组

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

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

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

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

jQuery如何处理类数组的

makeArray: function( arr, results ) {
 var ret = results || [];
 if ( arr != null ) {
  if ( isArraylike( Object(arr) ) ) {
   jQuery.merge( ret,
    typeof arr === "string" ?
    [ arr ] : arr
   );  //jQuery.merge 合并数组 ,若是字符串则封装成数组河滨,不是则世界合并
  } else {
   push.call( ret, arr );
  }
 }
 return ret;
}

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

toArray: function(iterable, start, end) {
    if (!iterable || !iterable.length) {
     return [];  //非类数组类型直接返回[]
    }
    if (typeof iterable === 'string') {
     iterable = iterable.split('');  //分解字符串
    }
    if (supportsSliceOnNodeList) {
     return slice.call(iterable, start || 0, end || iterable.length); //对于NodeList支持
    }
    var array = [],
     i;
    start = start || 0;
    end = end ? ((end < 0) ? iterable.length + end : end) : iterable.length;
    for (i = start; i < end; i++) {
     array.push(iterable[i]);
    }
    return array;
   }

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

slice: W3C ? function(nodes, start, end) { //var W3C = DOC.dispatchEvent; IE9开始支持W3C的事件模型
 return factorys.slice.call(nodes, start, end);
} : function(nodes, start, end) {
 var ret = [],
   n = nodes.length;
 if (end === void 0 || typeof end === "number" && isFinite(end)) {
  start = parseInt(start, 10) || 0;
  end = end == void 0 ? n : parseInt(end, 10);
  if (start < 0) {
   start += n;
  }
  if (end > n) {
   end = n;
  }
  if (end < 0) {
   end += n;
  }
  for (var i = start; i < end; ++i) {
   ret[i - start] = nodes[i];
  }
 }
 return ret;

以上就是本文的全部内容,希望对大家的学习有所帮助

Javascript 相关文章推荐
javascript 支持ie和firefox杰奇翻页函数
Jul 22 Javascript
jquery实现多级下拉菜单的实例代码
Oct 02 Javascript
JS二维数组的定义说明
Mar 03 Javascript
jQuery多项选项卡的实现思路附样式及代码
Jun 03 Javascript
jQuery中fadeOut()方法用法实例
Dec 24 Javascript
基于JavaScript实现仿京东图片轮播效果
Nov 06 Javascript
webix+springmvc session超时跳转登录页面
Oct 30 Javascript
浅析jQuery操作select控件的取值和设值
Dec 07 Javascript
vue.js中指令Directives详解
Mar 20 Javascript
vue中img src 动态加载本地json的图片路径写法
Apr 25 Javascript
微信小程序发布新版本时自动提示用户更新的方法
Jun 07 Javascript
vue webpack build资源相对路径的问题及解决方法
Jun 04 Javascript
jquery代码实现多选、不同分享功能
Jul 31 #Javascript
Jquery实现瀑布流布局(备有详细注释)
Jul 31 #Javascript
jquery实现仿JqueryUi可拖动的DIV实例
Jul 31 #Javascript
jQuery+css3实现文字跟随鼠标的上下抖动
Jul 31 #Javascript
JavaScript实现图片轮播的方法
Jul 31 #Javascript
基于bootstrap3和jquery的分页插件
Jul 31 #Javascript
jquery-tips悬浮提示插件分享
Jul 31 #Javascript
You might like
shell脚本作为保证PHP脚本不挂掉的守护进程实例分享
2013/07/15 PHP
php实现的短网址算法分享
2014/06/20 PHP
ThinkPHP 5.x远程命令执行漏洞复现
2019/09/23 PHP
php传值和传引用的区别点总结
2019/11/19 PHP
漂亮的提示信息(带箭头)
2007/03/21 Javascript
javascript 操作文件 实现方法小结
2009/07/02 Javascript
js取得html iframe中的元素和变量值
2014/06/30 Javascript
JavaScript实现点击按钮字体放大、缩小
2016/02/29 Javascript
AngularJs页面筛选标签小功能
2016/08/01 Javascript
JavaScript实现刷新不重记的倒计时
2016/08/10 Javascript
简单实现IONIC购物车功能
2017/01/10 Javascript
从零学习node.js之mysql数据库的操作(五)
2017/02/24 Javascript
Vue如何引入远程JS文件
2017/04/20 Javascript
jQuery中each循环的跳出和结束实例
2017/08/16 jQuery
element-ui多文件上传的实现示例
2019/04/10 Javascript
d3.js 地铁轨道交通项目实战
2019/11/27 Javascript
Vant+postcss-pxtorem 实现浏览器适配功能
2021/02/05 Javascript
[01:05:41]EG vs Optic Supermajor 败者组 BO3 第二场 6.6
2018/06/07 DOTA
在Gnumeric下使用Python脚本操作表格的教程
2015/04/14 Python
Python使用ftplib实现简易FTP客户端的方法
2015/06/03 Python
python3实现指定目录下文件sha256及文件大小统计
2019/02/25 Python
详解PyCharm+QTDesigner+PyUIC使用教程
2019/06/13 Python
python pandas模块基础学习详解
2019/07/03 Python
Python程序暂停的正常处理方法
2019/11/07 Python
python GUI库图形界面开发之PyQt5切换按钮控件QPushButton详细使用方法与实例
2020/02/28 Python
HTML5实现文件断点续传的方法
2017/01/04 HTML / CSS
Pandora西班牙官方商店:PandoraShop.es
2020/10/05 全球购物
JSF界面控制层技术
2013/06/17 面试题
如何安装ruby on rails
2014/02/09 面试题
国际政治个人自荐信范文
2013/11/26 职场文书
优良学风班申请材料
2014/02/13 职场文书
进口业务员岗位职责
2014/04/06 职场文书
个人委托书范本汇总
2014/10/01 职场文书
怎样写观后感
2015/06/19 职场文书
同学聚会感言一句话
2015/07/30 职场文书
多人盗宝《绿林侠盗》第三赛季4.5上线 跨平台实装
2022/04/03 其他游戏