需要预习:call , typeof, 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后是一个三元运算符:等价于

 if(typeof obj === "object" || typeof obj === "function"){
// 因为上文提到存在typeof /s/ 为 function的情况,所以需要toString详细判断
// 对于判断不出的数据类型默认为object
retrun class2type[ toString.call( obj ) ] || "object";
} else {
// 通过上面typeof对类型判断的表格,判断非object function还是很可靠的,所以直接用原生方法
return typeof obj;
}

结论: 通过用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属性

看jquery3.3.1学js类型判断的技巧的更多相关文章

  1. 类型和原生函数及类型转换(二:终结js类型判断)

    typeof instanceof isArray() Object.prototype.toString.call() DOM对象与DOM集合对象的类型判断 一.typeof typeof是一个一元 ...

  2. JS类型判断typeof PK {}.toString.call(obj)

    参考链接:https://www.talkingcoder.com/article/6333557442705696719 先看typeof <!doctype html> <htm ...

  3. js类型判断-丰富加好用

    一, 自己有时候写一些东西,要做类型判断,还有测试的时候,对于原生的和jQuery中的类型判断,实在不敢恭维,所以就写了一个好用的类型判断,一般情况都够用的. function test(type) ...

  4. JS类型判断&原型链

    JS类型检测主要有四种 1.typeof Obj 2.L instanceof R 3.Object.prototype.toString.call/apply(); 4.Obj.constructo ...

  5. js类型判断:typeof与instanceof

    typeof用以获取一个变量或者表达式的类型,typeof一般只能返回如下几个结果: number,boolean,string,function(函数),object(NULL,数组,对象),und ...

  6. js类型判断

    console.log('---------------------'); var a="string"; console.log(a); //string var a=1; co ...

  7. js类型判断及鸭式辨型

    目录 instanceof constructor 构造函数名字 鸭式辨型 三种检测对象的类方式: instanceof.constructor .构造函数名字 用法如下: 1)instanceof ...

  8. js类型判断的方法

    var arr=[]; alert(Object.prototype.toString.call(arr)=='[object Array]');

  9. js 类型判断

随机推荐

  1. 关于Axure RP

    Axure RP 是一款专业的原型设计工具 用于快速创建应用软件的线框图.流程图.原型和规格说明文档 贴一张图

  2. BZOJ 1050 旅行(并查集)

    很好的一道题.. 首先把边权排序.然后枚举最小的边,再依次添加不小于该边的边,直到s和t联通.用并查集维护即可. # include <cstdio> # include <cstr ...

  3. 前端开发学习之——使用jquery/javascript判断及改变checkbox选中状态

    一.使用jquery判断及改变checkbox选中状态 1.使用JQuery判断一个checkbox 是否为选中: (1).attr('checked) 看JQuery版本1.6+返回:”checke ...

  4. [NOI2006]网络收费

    题面在这里 description 一棵\(2^n\)个叶节点的满二叉树,每个节点代表一个用户,有一个预先的收费方案\(A\)或\(B\); 对于任两个用户 \(i,j(1≤i<j≤2^n)i, ...

  5. C++中数组和vector

    本文基于邓俊辉编著<数据结构(C++语言版)(第3版)>.<C++ Primer(第5版)>以及网上的相关博文而写,博主水平有限,若有不妥处,欢迎指出. 一.数组 C++中数组 ...

  6. SELECT LAST_INSERT_ID() 的使用和注意事项

    SELECT LAST_INSERT_ID() 的使用和注意事项 尊重个人劳动成果,转载请注明出处: http://blog.csdn.net/czd3355/article/details/7130 ...

  7. MYSQL性能察看

    http://fengbin2005.iteye.com/blog/1580214 网上有很多的文章教怎么配置MySQL服务器,但考虑到服务器硬件配置的不同,具体应用的差别,那些文章的做法只能作为初步 ...

  8. 题解 【luogu P2680 NOIp提高组2015 运输计划】

    题目链接 题解 题意 一棵树上有\(m\)条路径,可以将其中一条边的权值改为0,问最长的路径最短是多少 分析 最短的路径最长自然想到二分最长路径,设其为\(dis\) 关键在于如何check chec ...

  9. 深度学习---tensorflow简介

    个core可以有不同的代码路径.对于反向传播算法来说,基本计算就是矩阵向量乘法,对一个向量应用激活函数这样的向量化指令,而不像在传统的代码里会有很多if-else这样的逻辑判断,所以使用GPU加速非常 ...

  10. sublime 常用插件 感觉比较全了 够用了

    插件介绍 Package Control 功能:安装包管理 简介:sublime插件控制台,提供添加.删除.禁用.查找插件等功能 使用:https://sublime.wbond.net/instal ...