通过jQuery学习js类型判断的技巧
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中所有存在的值
问题一:我们都知道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 数据结构如下:
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学习js类型判断的技巧
-
js判断undefined类型,undefined,null, 的区别详细解析_javascript技巧
-
js判断浏览器类型的方法_javascript技巧
-
js判断上传文件的类型和大小示例代码_javascript技巧
-
js判断浏览器类型,版本的代码(附多个实例代码)_javascript技巧
-
JS判断浏览器类型与版本的实现代码_javascript技巧
-
结合JQ1.9通过js正则判断各种浏览器版本的方法_jquery
-
判断输入是否为空,获得输入类型的JS代码_javascript技巧
-
js判断浏览器类型,版本的代码(附多个实例代码)_javascript技巧
-
js判断上传文件的类型和大小示例代码_javascript技巧