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 同时提交多个Web表单的方法
Feb 19 Javascript
预加载css或javascript的js代码
Apr 23 Javascript
基于jquery循环map功能的代码
Feb 26 Javascript
jQuery LigerUI 使用教程表格篇(1)
Jan 18 Javascript
使用Jquery实现点击文字后变成文本框且可修改
Sep 21 Javascript
ajax分页效果(bootstrap模态框)
Jan 23 Javascript
layui前段框架日期控件使用方法详解
May 19 Javascript
ReactNative之FlatList的具体使用方法
Nov 29 Javascript
layer提示框添加多个按钮选择的实例
Sep 12 Javascript
Vue v-for循环之@click点击事件获取元素示例
Nov 09 Javascript
小程序实现上下切换位置
Nov 16 Javascript
js实现上传图片到服务器
Apr 11 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
用PHP实现多级树型菜单
2006/10/09 PHP
php checkbox 取值详细说明
2010/08/19 PHP
10条php编程小技巧
2015/07/07 PHP
php项目中百度 UEditor 简单安装调试和调用
2015/07/15 PHP
yii实现使用CUploadedFile上传文件的方法
2015/12/28 PHP
Ubuntu VPS中wordpress网站打开时提示”建立数据库连接错误”的解决办法
2016/11/03 PHP
Jquery Ajax学习实例4 向WebService发出请求,返回实体对象的异步调用
2010/03/16 Javascript
同时使用n个window onload加载实例介绍
2013/04/25 Javascript
js中一个函数获取另一个函数返回值问题探讨
2013/11/21 Javascript
jQuery 1.9移除了$.browser可以使用$.support来替代
2014/09/03 Javascript
浏览器缩放检测的js代码
2014/09/28 Javascript
jQuery制作简单柱状图实例
2015/01/28 Javascript
js中hash和ico的关联分析
2015/02/05 Javascript
js禁止页面刷新与后退的方法
2015/06/08 Javascript
详解JavaScript对象和数组
2015/12/03 Javascript
深入解析JavaScript中函数的Currying柯里化
2016/03/19 Javascript
基于jquery插件编写countdown计时器
2016/06/12 Javascript
jQuery stop()用法实例详解
2016/07/28 Javascript
js 创建对象 经典模式全面了解
2016/08/16 Javascript
Node.js和Express简单入门介绍
2017/03/24 Javascript
详解Nodejs内存治理
2018/05/13 NodeJs
详解使用element-ui table组件的筛选功能的一个小坑
2018/11/02 Javascript
Vue修改项目启动端口号方法
2019/11/07 Javascript
javascript History对象原理解析
2020/02/17 Javascript
[01:56]林书豪DOTA2上海特级锦标赛励志短片
2016/03/05 DOTA
Python的时间模块datetime详解
2017/04/17 Python
Python递归调用实现数字累加的代码
2020/02/25 Python
python+flask编写一个简单的登录接口
2020/11/13 Python
CSS3教程(5):网页背景图片
2009/04/02 HTML / CSS
HTML5 canvas基本绘图之填充样式实现
2016/06/27 HTML / CSS
物流专员岗位职责
2014/02/17 职场文书
卫生院艾滋病宣传活动总结
2015/05/09 职场文书
刑事上诉状(无罪)
2015/05/23 职场文书
2016年度继续教育学习心得体会
2016/01/19 职场文书
导游词之澳门妈祖庙
2019/12/19 职场文书
MySQL下使用Inplace和Online方式创建索引的教程
2021/05/26 MySQL