通过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和原生JavaScript实现网页定位导航特效
Apr 03 jQuery
基于jQuery Easyui实现登陆框界面
Jul 10 jQuery
使用jQuery实现动态添加小广告
Jul 11 jQuery
jQuery条件分页 代替离线查询(附代码)
Aug 17 jQuery
jQuery实现table中两列CheckBox只能选中一个的示例
Sep 22 jQuery
jquery鼠标悬停导航下划线滑出效果
Sep 29 jQuery
vue-cli webpack 引入jquery的方法
Jan 10 jQuery
jQuery与vue实现拖动验证码功能
Jan 30 jQuery
jQuery替换节点元素的操作方法
Mar 18 jQuery
JQuery元素快速查找与操作
Apr 22 jQuery
jQuery常见的遍历DOM操作详解
Sep 05 jQuery
jQuery实现判断滚动条滚动到document底部的方法分析
Aug 27 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
MySQL连接数超过限制的解决方法
2011/07/17 PHP
php过滤html标记属性类用法实例
2014/09/23 PHP
php实现统计二进制中1的个数算法示例
2018/01/23 PHP
php转换上传word文件为PDF的方法【基于COM组件】
2019/06/10 PHP
js调用flash的效果代码
2008/04/26 Javascript
一步一步制作jquery插件Tabs实现过程
2010/07/06 Javascript
Javascript 命名空间模式
2013/11/01 Javascript
轻松创建nodejs服务器(1):一个简单nodejs服务器例子
2014/12/18 NodeJs
js表头排序实现方法
2015/01/16 Javascript
jquery制作 随机弹跳的小球特效
2015/02/01 Javascript
jquery动态添加删除(tr/td)
2015/02/09 Javascript
JS组件Bootstrap导航条使用方法详解
2016/04/29 Javascript
javascript解决小数的加减乘除精度丢失的方案
2016/05/31 Javascript
JS文件上传神器bootstrap fileinput详解
2021/01/28 Javascript
javascript实现简单的ajax封装示例
2016/12/28 Javascript
javascript解析ajax返回的xml和json格式数据实例详解
2017/01/05 Javascript
JS实现的简单四则运算计算器功能示例
2017/09/27 Javascript
webpack 模块热替换原理
2018/04/09 Javascript
手把手15分钟搭一个企业级脚手架
2019/09/16 Javascript
[20:30]职业巡回赛回顾
2018/08/09 DOTA
[00:52]玛尔斯技能全介绍
2019/03/06 DOTA
[01:00:13]完美世界DOTA2联赛 LBZS vs Forest 第一场 11.07
2020/11/09 DOTA
python实现定制交互式命令行的方法
2014/07/03 Python
Tornado服务器中绑定域名、虚拟主机的方法
2014/08/22 Python
对numpy中二进制格式的数据存储与读取方法详解
2018/11/01 Python
Django项目主urls导入应用中views的红线问题解决
2019/08/10 Python
python如何实现不用装饰器实现登陆器小程序
2019/12/14 Python
python matplotlib画盒图、子图解决坐标轴标签重叠的问题
2020/01/19 Python
Python列表倒序输出及其效率详解
2020/03/04 Python
解决pytorch 交叉熵损失输出为负数的问题
2020/07/07 Python
size?德国官方网站:英国伦敦的球鞋精品店
2018/03/17 全球购物
德国BA保镖药房中文网:Bodyguard Apotheke
2021/03/09 全球购物
毕业生物理教师求职信
2013/10/17 职场文书
十佳文明家庭事迹
2014/05/25 职场文书
商超业务员岗位职责
2015/02/13 职场文书
如何用JS实现网页瀑布流布局
2021/04/24 Javascript