通过jQuery学习js类型判断的技巧


Posted in jQuery onMay 27, 2019

1. isFunction中typeof的不靠谱

源码:

var isFunction = function isFunction( obj ) {
// Support: Chrome <=57, Firefox <=52
// In some browsers, typeof returns "function" for HTML <object> elements
// (i.e., `typeof document.createElement( "object" ) === "function"`).
// We don't want to classify *any* DOM node as a function.
return typeof obj === "function" && typeof obj.nodeType !== "number";
};

typeof 是为了区分数据类型,下面是MDN中总结的typeof中所有存在的值

通过jQuery学习js类型判断的技巧

问题一:我们都知道typeof null 出来的结果是‘object',可这是为啥呢?MDN给出了答案 :因为null是空指针,而空指针在大多数平台中使用0x00表示,而js在实现初期通过用 0 作为对象的标签,所以对null也被判断为object。

问题二:既然typeof能够判断出function,为何jquery额外判断 typeof obj.nodeType !== "number" 呢?

long long ago,在那些古老的浏览器中:

1. typeof document.body.childNodes // function 这在古老的 safari 3 中会出现

2.typeof document.createElement("object") // function 同理还有 'embed' 'applet' , 在古老的firefox中会出现,目前新版本不会存在

3.typeof /s/ // function 这种情况会在古老浏览器中出现,目前都会被判定为 object

通过以上问题我们可以看出,通过typeof判断数据类型在古老的浏览器中是极为不靠谱的,所以在jquery的isFunction的判断中额外添加了判断 检测对象是否为dom 对象2.靠谱的数据类型判断

源码:

var class2type = {};
var toString = class2type.toString;
// Populate the class2type map,这里并没有undefined
jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
function( i, name ) {
class2type[ "[object " + name + "]" ] = name.toLowerCase();
} );
function toType( obj ) {
if ( obj == null ) {
return obj + "";
}
// Support: Android <=2.3 only (functionish RegExp)
return typeof obj === "object" || typeof obj === "function" ?
class2type[ toString.call( obj ) ] || "object" :
typeof obj;
}

在代码中jquery做了这几件事:

1.jquery先提取出toString 这个方法

2.将写好的类型字符串分割并存入class2type中,class2type 数据结构如下:

通过jQuery学习js类型判断的技巧

3.定义toType方法,因为 toString(null)会得出‘ [object Undefined]'的结果,所以需要把null单独判断,注意null是没有toString这个方法的,所以通过 obj+''这个方式得到 'null'

4.在单独判断null后是一个三元运算符:等价于

1 if(typeof obj === "object" || typeof obj === "function"){
2 // 因为上文提到存在typeof /s/ 为 function的情况,所以需要toString详细判断
3 // 对于判断不出的数据类型默认为object
4 retrun class2type[ toString.call( obj ) ] || "object";
5 } else {
6 // 通过上面typeof对类型判断的表格,判断非object function还是很可靠的,所以直接用原生方法
7 return typeof obj;
8 }

结论: 通过用toString方法可以判断出Boolean、Number、 String、 Function、 Array、 Date、 RegExp、 Object、 Error、 Symbol、undefined 这些数据类型,但是并不能判断出null,所以要综合判断,就酱

除此之外jquery还额外判断了当前对象是否为window,只用了如下的方法:

var isWindow = function isWindow( obj ) {
return obj != null && obj === obj.window;
};

前方的obj!=null 是为了防止开发人员在调用函数 isWindow时传入null 、undefined的时候报Uncaught TypeError: Cannot read property 'window' of null/undefined的错误。

还有isArrayLike,判断当前对象是不是类数组对象,类数组对象是什么,建议大家百度一下

function isArrayLike( obj ) {
// Support: real iOS 8.2 only (not reproducible in simulator)
// `in` check used to prevent JIT error (gh-2145)
// hasOwn isn't used here due to false negatives
// regarding Nodelist length in IE
var length = !!obj && "length" in obj && obj.length,
type = toType( obj );
if ( isFunction( obj ) || isWindow( obj ) ) {
return false;
}
return type === "array" || length === 0 ||
typeof length === "number" && length > 0 && ( length - 1 ) in obj;
}

首先判断obj中是否有length属性并取出length

然后排除obj是否是window 及 function

最后取值条件:1.是否是array(类数组对象集合当然包括数组) 2.存在length属性但length是0 3.判定length是数字且大于零,并在obj对象中存在length-1属性

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

jQuery 相关文章推荐
jQuery Validate 无法验证 chosen-select元素的解决方法
May 17 jQuery
JQuery 封装 Ajax 常用方法(推荐)
May 21 jQuery
jQuery制作全屏宽度固定高度轮播图(实例讲解)
Jul 08 jQuery
jQuery实现节点的追加、替换、删除、复制功能示例
Jul 11 jQuery
Vue+jquery实现表格指定列的文字收缩的示例代码
Jan 09 jQuery
通过jquery toggleClass()属性制作文章段落更改背景颜色
May 21 jQuery
jquery分页插件pagination使用教程
Oct 23 jQuery
jQuery实现的点击图片居中放大缩小功能示例
Jan 16 jQuery
jquery 验证用户名是否重复代码实例
May 14 jQuery
jquery实现购物车基本功能
Oct 25 jQuery
jQuery实现的分页插件完整示例
May 26 jQuery
jquery实现抽奖功能
Oct 22 jQuery
jQuery中使用validate插件校验表单功能
May 24 #jQuery
jQuery操作attr、prop、val()/text()/html()、class属性
May 23 #jQuery
jquery+php后台实现省市区联动功能示例
May 23 #jQuery
jQuery Migrate 插件用法实例详解
May 22 #jQuery
jQuery实现的鼠标拖动画矩形框示例【可兼容IE8】
May 17 #jQuery
jQuery实现的点击显示隐藏下拉菜单功能完整示例
May 17 #jQuery
jQuery控制input只能输入数字和两位小数的方法
May 16 #jQuery
You might like
德劲1103二次变频版的打磨
2021/03/02 无线电
PHP 文件类型判断代码
2009/03/13 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(十六)
2014/06/30 PHP
jquery的extend和fn.extend的使用说明
2011/01/09 Javascript
javascript瀑布流式图片懒加载实例
2020/06/28 Javascript
js实现鼠标左右移动,图片也跟着移动效果
2017/01/25 Javascript
判断横屏竖屏(三种)
2017/02/13 Javascript
教你快速搭建Node.Js服务器的方法教程
2017/03/30 Javascript
AngularJS 异步解决实现方法
2017/06/12 Javascript
JS使用tofixed与round处理数据四舍五入的区别
2017/10/25 Javascript
实例解析ES6 Proxy使用场景介绍
2018/01/08 Javascript
element-ui使用导航栏跳转路由的用法详解
2018/08/22 Javascript
详解Webstorm 下的Angular2.0开发之路(图文)
2018/12/06 Javascript
vue-cli脚手架的.babelrc文件用法说明
2020/09/11 Javascript
Vue解决移动端弹窗滚动穿透问题
2020/12/15 Vue.js
python基于socket实现网络广播的方法
2015/04/29 Python
python获取目录下所有文件的方法
2015/06/01 Python
利用python实现简单的邮件发送客户端示例
2017/12/23 Python
Django实现学员管理系统
2019/02/26 Python
Python OpenCV实现视频分帧
2019/06/01 Python
Django实现微信小程序的登录验证功能并维护登录态
2019/07/04 Python
python处理自动化任务之同时批量修改word里面的内容的方法
2019/08/23 Python
python取均匀不重复的随机数方式
2019/11/27 Python
Pytorch 使用 nii数据做输入数据的操作
2020/05/26 Python
python 输入字符串生成所有有效的IP地址(LeetCode 93号题)
2020/10/15 Python
HTML5之SVG 2D入门13—svg对决canvas及长处和适用场景分析
2013/01/30 HTML / CSS
html5 offlline 缓存使用示例
2013/06/24 HTML / CSS
西班牙购买隐形眼镜、眼镜和太阳镜网站:Lentiamo.es
2020/06/11 全球购物
大学生如何写自荐信
2014/01/08 职场文书
婚礼主持词
2014/03/13 职场文书
校运会加油稿大全
2015/07/22 职场文书
生产实习心得体会范文
2016/01/22 职场文书
2019年学校消防安全责任书(2篇)
2019/10/09 职场文书
如何将numpy二维数组中的np.nan值替换为指定的值
2021/05/14 Python
python可视化大屏库big_screen示例详解
2021/11/23 Python
【海涛教你打DOTA】剑圣第一人称视角解说
2022/04/01 DOTA