jQuery的XX如何实现?——4.类型检查
往期回顾:
jQuery的XX如何实现?——3.data与cache机制
--------------------------
源码链接:内附实例代码
jQuery使用许久了,但是有一些API的实现实在想不通。于是抽空看了jQuery源码,现在把学习过程中发现的一些彩蛋介绍给大家(⊙0⊙)。
下面将使用简化的代码来介绍,主要关注jQuery的实现思想~>_<~
相较于第一篇(与第二、三篇无相关性),代码更新了:26~40
本章主要通过isFunction、isWindow、isNumberic三个的工具方法来学习类型检测和工具方法的定义。
1 (function(window, undefined){ 2 3 function jQuery(sel){ 4 return new jQuery.prototype.init(sel); 5 } 6 7 jQuery.prototype = { 8 constructor: jQuery, 9 init: function(sel){ 10 if(typeof sel === 'string'){ 11 var that = this; 12 var nodeList = document.querySelectorAll(sel); 13 Array.prototype.forEach.call(nodeList, function(val, i){ 14 that[i] = val; 15 }) 16 this.selector = sel; 17 this.length = nodeList.length; 18 } 19 } 20 } 21 22 jQuery.prototype.init.prototype = jQuery.prototype; 23 24 window.$ = jQuery; 25 26 jQuery.isFunction = function(obj) { 27 return typeof obj === 'function'; 28 } 29 30 //window.window 有点意思 31 jQuery.isWindow = function(obj) { 32 return obj && obj === obj.window; 33 } 34 35 jQuery.isNumberic = function(obj) { 36 //return typeof obj === 'number'; 37 //return Object.prototype.toString.call(obj) === '[object Number]'; //发现情况一模一样 38 //return !isNaN(obj) && isFinite(obj); //漏了null 39 return !isNaN(parseFloat(obj)) && isFinite(obj); 40 } 41 42 })(window);
--------------------------
类型检测属于工具方法里的一种。可以看出,工具方法是直接绑定在jQuery对象下的。
isFunction的方法实现起来非常简单,内部使用typeof检测一下就ok了o(≧v≦)o~~
jQuery.isFunction = function(){ return typeof obj === 'function'; } //外部调用 $.isFunction(fun1);
--------------------------
isWindow实现起来需要点技巧:全局变量都绑定在window下,window本身也在全局变量中,所以可以通过window访问window。
//(⊙0⊙) 有点意思 window.window.window
使用这个小技巧,可以写出代码:
jQuery.isWindow = function(obj) { return obj && obj === obj.window; //觉得可以简化成 //return window === obj; }
--------------------------
最后来个稍复杂点的isNumberic(isNumber),我们先列出所有可能的验证数据:
1, '1', '1cm', 'cm1', 2e64, '2e64', NaN, Infinity, null
先试试用typeof检测一下
jQuery.isNumberic = function(obj) { return typeof obj === 'number'; }
看完结果,怒吼一声,typeof你个垃鸡ψ(╰_╯):
突然灵机一动,可以试一下用Object.prototype.toString来检测,说干就干:
jQuery.isNumberic = function(obj) { return Object.prototype.toString.call(obj) === '[object Number]'; }
发现,结果一模一样(⊙0⊙)。
没办法,只能得先回到typeof。只差这四个没检测过了,分析一下,立马想到isNaN和isFinite两个函数。
'1', '2e64', NaN, Infinity
假装写了代码,然后发现isNaN和isFinite两者一结合,把typeof的事情也干了。于是顺理成章地删掉typeof,得到:
【不知道这两个函数的作用,直接拉到最下面,有贴心的小例子╰( ̄▽ ̄)╮】
jQuery.isNumberic = function(obj) { return !isNaN(obj) && isFinite(obj); }
运行一下,看完有点小激动,只剩下null了o(≧v≦)o~~:
分析后,是因为isFinite(null)返回true。
最后代码可修改为注释那行,jQuery源码中为未注释那行,目测效果都一样(⊙0⊙):
jQuery.isNumberic = function(obj) { return !isNaN(parseFloat(obj)) && isFinite(obj); //return obj!=null && !isNaN(obj) && isFinite(obj) }
最后发现漏检查了undefined,测试之后发现没问题~>_<~+
--------------------------
附录:
-----------------------------------------
(⊙0⊙)如果该博文有用,记得点个赞哦
转载指明出处即可╰( ̄▽ ̄)╮
欢迎讨论o(≧v≦)o~~