通过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和ajax代替iframe的方法(详解)
Apr 12 jQuery
jQuery输入框密码的显示隐藏【代码分享】
Apr 29 jQuery
jQuery用户头像裁剪插件cropbox.js使用详解
Jun 07 jQuery
jQuery remove()过滤被删除的元素(推荐)
Jul 18 jQuery
使用jquery+iframe做一个ajax上传效果(实例)
Aug 24 jQuery
jQuery实现所有验证通过方可提交的表单验证
Nov 21 jQuery
jquery中done和then的区别(详解)
Dec 19 jQuery
jquery实现企业定位式导航效果
Jan 01 jQuery
jQuery实现输入框的放大和缩小功能示例
Jul 21 jQuery
vue-cli 引入jQuery,Bootstrap,popper的方法
Sep 03 jQuery
jquery分页插件pagination使用教程
Oct 23 jQuery
jQuery 图片查看器插件 Viewer.js用法简单示例
Apr 04 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
PHP中实现图片的锐化
2006/10/09 PHP
提取HTML标签
2006/10/09 PHP
PHP chmod 函数与批量修改文件目录权限
2010/05/10 PHP
PHP中unset,array_splice删除数组中元素的区别
2014/07/28 PHP
Laravel 4 初级教程之视图、命名空间、路由
2014/10/30 PHP
php中ob_get_length缓冲与获取缓冲长度实例
2014/11/20 PHP
php微信公众号开发(3)php实现简单微信文本通讯
2016/12/15 PHP
超清晰的document对象详解
2007/02/27 Javascript
禁止JQuery中的load方法装载IE缓存中文件的方法
2009/09/11 Javascript
jQuery1.6 使用方法二
2011/11/23 Javascript
EXTjs4.0的store的findRecord的BUG演示代码
2013/06/08 Javascript
js 弹出框只弹一次(二次修改之后的)
2013/11/26 Javascript
html dom节点操作(获取/修改/添加或删除)
2014/01/23 Javascript
常用DOM整理
2015/06/16 Javascript
js实现的简单radio背景颜色选择器代码
2015/08/18 Javascript
Ionic2调用本地SQlite实例
2017/04/22 Javascript
详解vue嵌套路由-params传递参数
2017/05/23 Javascript
vue.js使用3DES加密的方法示例
2018/05/18 Javascript
Vue 路由 过渡动效 数据获取方法
2018/07/31 Javascript
vue 开发企业微信整合案例分析
2019/12/02 Javascript
微信小程序实现抖音播放效果的实例代码
2020/04/11 Javascript
Javascript原型链及instanceof原理详解
2020/05/25 Javascript
解决Vue 移动端点击出现300毫秒延迟的问题
2020/07/21 Javascript
简单介绍使用Python解析并修改XML文档的方法
2015/10/15 Python
django多文件上传,form提交,多对多外键保存的实例
2019/08/06 Python
手把手教你pycharm专业版安装破解教程(linux版)
2019/09/26 Python
python中uuid模块实例浅析
2020/12/29 Python
HTML5不支持frameset的两种解决方法
2016/11/14 HTML / CSS
日本7net购物网:书籍、漫画、杂志、DVD、游戏邮购
2017/02/17 全球购物
美国廉价机票预订网站:Cheapfaremart
2018/04/28 全球购物
COSETTE官网:奢华,每天
2020/03/22 全球购物
2015届大学生就业推荐表自我评价
2014/09/27 职场文书
旷课检讨书500字
2014/10/14 职场文书
《植树问题》教学反思
2016/03/03 职场文书
Ajax常用封装库——Axios的使用
2021/05/08 Javascript
如何用JavaScipt测网速
2021/05/09 Javascript