通过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日历价格、库存等设置插件
Jul 05 jQuery
原生js jquery ajax请求以及jsonp的调用方法
Aug 04 jQuery
利用JQUERY实现多个AJAX请求等待的实例
Dec 14 jQuery
jQuery+SpringMVC中的复选框选择与传值实例
Jan 08 jQuery
解决Jquery下拉框数据动态获取的问题
Jan 25 jQuery
jQuery实现form表单序列化转换为json对象功能示例
May 23 jQuery
AJAX在JQuery中的应用详解
Jan 30 jQuery
JQuery常见节点操作实例分析
May 15 jQuery
jquery插件开发模式实例详解
Jul 20 jQuery
JQuery样式与属性设置方法分析
Dec 07 jQuery
jQuery操作选中select下拉框的值代码实例
Feb 07 jQuery
jQuery实现二级导航菜单的示例
Sep 30 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
动态生成gif格式的图像要注意?
2006/10/09 PHP
php创建多级目录的方法
2015/03/24 PHP
CodeIgniter集成smarty的方法详解
2016/05/26 PHP
PHP判断访客是否手机端(移动端浏览器)访问的方法总结【4种方法】
2019/03/27 PHP
laravel7学习之无限级分类的最新实现方法
2020/09/30 PHP
JQuery1.4+ Ajax IE8 内存泄漏问题
2010/10/15 Javascript
使用UglifyJS合并/压缩JavaScript的方法
2012/03/07 Javascript
Javascript Request获取请求参数如何实现
2012/11/28 Javascript
关于js内存泄露的一个好例子
2013/12/09 Javascript
D3.js 从P元素的创建开始(显示可加载数据)
2014/10/30 Javascript
探寻Javascript执行效率问题
2014/11/12 Javascript
javascript 操作符(~、&amp;、|、^、)使用案例
2014/12/31 Javascript
原生JS和JQuery动态添加、删除表格行的方法
2015/05/28 Javascript
JS实现兼容性好,带缓冲的动感网页右键菜单效果
2015/09/18 Javascript
jQuery实现checkbox列表的全选、反选功能
2016/11/24 Javascript
Bootstrap的基本应用要点浅析
2016/12/19 Javascript
微信小程序开发之麦克风动画 帧动画 放大 淡出
2017/04/18 Javascript
浅谈Vue项目骨架屏注入实践
2019/08/05 Javascript
JavaScript实现身份证验证代码实例
2019/08/26 Javascript
node.js中Buffer缓冲器的原理与使用方法分析
2019/11/23 Javascript
viewer.js实现图片预览功能
2020/06/24 Javascript
[06:07]DOTA2-DPC中国联赛 正赛 Ehome vs VG 选手采访
2021/03/11 DOTA
python插入数据到列表的方法
2015/04/30 Python
python代码 if not x: 和 if x is not None: 和 if not x is None:使用介绍
2016/09/21 Python
python删除文本中行数标签的方法
2018/05/31 Python
Pyqt5自适应布局实例
2019/12/13 Python
tensorflow如何继续训练之前保存的模型实例
2020/01/21 Python
python实现读取类别频数数据画水平条形图案例
2020/04/24 Python
世界上最大的巴士旅游观光公司:Big Bus Tours
2016/10/20 全球购物
德国机场停车位比较和预订网站:Ich-parke-billiger
2018/01/08 全球购物
疾病防治方案
2014/05/31 职场文书
党的群众路线专项整治方案
2014/11/03 职场文书
个人自荐书范文
2015/03/09 职场文书
JavaScript中关于预编译、作用域链和闭包的理解
2021/03/31 Javascript
Redis持久化与主从复制的实践
2021/04/27 Redis
Win11 引入 Windows 365 云操作系统,适应疫情期间混合办公模式:启动时直接登录、模
2022/04/06 数码科技