35 综合专题之检测数据类型的四种方案2(剖析JQ源码,研究其数据检测的方法)

jQuery源码刨析

var class2type = {};
		var toString = class2type.toString; //=>Object.prototype.toString
		var hasOwn = class2type.hasOwnProperty; //=>Object.prototype.hasOwnProperty
		var fnToString = hasOwn.toString; //=>Function.prototype.toString
		var ObjectFunctionString = fnToString.call(Object); //=>Object.toString() =>"function Object() { [native code] }"

		"Boolean Number String Function Array Date RegExp Object Error Symbol".split(" ").forEach(function anonymous(item) {
			class2type["[object " + item + "]"] = item.toLowerCase();
		});
		console.log(class2type);
        // 学习参考封装
		function toType(obj) {
			//=>obj may be null / undefined
			//=>return "null"/"undefined"
			if (obj == null) {
				return obj + "";
			}

			return typeof obj === "object" || typeof obj === "function" ? class2type[toString.call(obj)] || "object" :
				typeof obj;
		}
		// jQuery.type = toType;

		//=>是否为函数
		var isFunction = function isFunction(obj) {
			return typeof obj === "function" && typeof obj.nodeType !== "number";
			// typeof obj.nodeType 是为了考虑老版本浏览器
		};

		//=>检测是否为window对象
		// window.window===window
		var isWindow = function isWindow(obj) {
			return obj != null && obj === obj.window;
			//window.window  还是返回window
		};

		//=>是否为纯粹的对象{}(数组和正则等都不是纯粹的对象)
		var isPlainObject = function isPlainObject(obj) {
			var proto, Ctor;
			if (!obj || toString.call(obj) !== "[object Object]") {
				return false;
			}
			//=>getPrototypeOf获取当前对象的原型
			proto = Object.getPrototypeOf(obj);
			// Objects with no prototype (`Object.create( null )`)
			// 如果非null
			if (!proto) {
				return true;
			}
			// Objects with prototype are plain iff they were constructed by a global Object function
			// 判断原型上是否有constructor,如果有就获取constructor,没有就返回false;并且 proto.constructor指向类本身
			Ctor = hasOwn.call(proto, "constructor") && proto.constructor;
			// 判断是否既是function,也是object
			return typeof Ctor === "function" && fnToString.call(Ctor) === ObjectFunctionString;
		};

		//=>是否为空对象
		// 看他是否能够for in循环,for in 跳过空元素
		var isEmptyObject = function isEmptyObject(obj) {
			var name;
			for (name in obj) {
				return false;
			}
			return true;
		};

		//=>是否为数组或者类数组
		var isArrayLike = function isArrayLike(obj) {
			// !obj 代表是否传东西了,先转化为boolean,有为true,取反为false, 再取反为true
			var length = !!obj && "length" in obj && obj.length,
				type = toType(obj);
				// window.length===0
			if (isFunction(obj) || isWindow(obj)) {
				return false;
			}
			// 运算符优先级,先算逻辑与&&,再算逻辑或||
			// 其中,length-1, 代表最大的索引
			return type === "array" || length === 0 || typeof length === "number" && length > 0 && (length - 1) in obj;
		};

知识点强调

运算符优先级,先算逻辑与&&,再算逻辑或||
其中,length-1, 代表最大的索引
! !obj 代表是否传东西了,先转化为boolean,有为true,取反为false, 再取反为true
··老是忘记··
const prototype1={‘name’:‘OBJ’}
const object1 = Object.create(prototype1)
Object.create 创建一个空对象,他的__proto__指向prototype1
getPrototypeOf()获取当前对象的原型这里的原型就是 prototype1

话术:
检测数据类型的常规就四种,typeof,instanceof,constructor,Object.prototype.toString.call()
我之前看过jq源码,它的原理是
对常见的数据类型大字符串用split以空格拆分,生成新的数组,然后循环数组中的每一项, 在class2type对象存放[‘Object Array’]=array 等字面量对象,然后检测是否为空,输出null或者undefined,再进行判断 是引用类型还是基本类型,如果是引用类型则进行calss2type对象比对,输出对应的属性值,否则就用typeof 检测。
之后,在项目上哪怕不用jq,我也会参考jq源码自己封装totype 方法。 -->

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值