JS中的钩子(hook)机制与实现 - Break易站
什么是钩子机制?使用钩子机制有什么好处?
钩子机制也叫hook机制,或者你可以把它理解成一种匹配机制,就是我们在代码中设置一些钩子,然后程序执行时自动去匹配这些钩子;这样做的好处就是提高了程序的执行效率,减少了if else 的使用同事优化代码结构。由于js是单线程的编程语言,所以程序的运行效率在前端开发是比较重要的,在开发中我们秉承如果能用switch case 的地方就不要用if else 可以用hook实现的尽量使用hook机制去实现。
hook机制也就是钩子机制,由表驱动实现,常用来处理多种特殊情况的处理。我们预定义了一些钩子,在常用的代码逻辑中去适配一些特殊的事件,这样可以让我们少些很多if else语句。
JS中的钩子(hook)的例子
JS中的钩子(hook)的例子1:
例如我们在向后台进行ajax请求的时候,后台经常会返回我们一些常见的错误码,如:001代表用户不存在,002代表用户密码输入错误。003代表用户被锁定。这个时候我们要将错误友好的提示给用户。这个时候我们该怎样实现呢?
一般的写法可能是:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | $.ajax(option, function (result){ var errCode = result.errCode ; //错误码 if (errCode){ if (errCode == '001' ){ alert( "用户不存在" ) } else if (errCode == '002' ){ alert( "密码输入错误" ) } else if (errCode == '003' ){ alert( "用户被锁定" ) } } else { //登录成功 } }, function (err){ }) |
这样写其实是比较low低,稍微有点经验的可能会使用switch case来实现,但是这个两种写法都无法避免一个问题就是如果我的错误码特别多,那得写多少个if else和case 啊?但是如果使用hook写法的话就会简单好多,
首先我们先声明一个错误码钩子列表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | var codeList = { "001" : "用户不存在" , "002" : "密码输入错误" , "003" : "用户被锁定" } $.ajax(option, function (result){ var errCode = result.errCode ; //错误码 if (!errCode){ alert(codeList[errCode]); } else { //登录成功 } }, function (err){ }) |
这样写的话代码结构更加清楚明了。这个例子是最简单的应用了的了。
JS中的钩子(hook)的例子2:
举个高考加分的例子,比如获得过全国一等奖加20分,二等奖加10分,三等奖加5分。使用if else的话:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | function student(name,score,praise){ return { name:name, score:score, praise:praise } } function praiseAdd(students){ var results={}; for ( var i in students){ var curStudent=students[i]; var ret=curStudent.score; if (curStudent.praise==1){ ret+=20; } else if (curStudent.praise==2){ ret+=10; } else if (curStudent.praise==3){ ret+=5; } results[curStudent.name]=ret; } return results; } var liming= student( "liming" ,70,1); var liyi= student( "liyi" ,90,2); var liuwei= student( "liuwei" ,80,3); var ertuzi= student( "ertuzi" ,85,3); var result=praiseAdd([liming,liyi,liuwei,ertuzi]); for ( var i in result){ console.log( "name:" +i+ ",score:" +result[i]); } |
如果是用钩子机制呢
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | function student(name,score,praise){ return { name:name, score:score, praise:praise } } var praiseList={ 1:20, 2:10, 3:5 } function praiseAdd(students){ var results={}; for ( var i in students){ var curStudent=students[i]; var ret=curStudent.score; if (praiseList[curStudent.praise]) ret+=praiseList[curStudent.praise]; results[curStudent.name] = ret; } return results; } var liming= student( "liming" ,70,1); var liyi= student( "liyi" ,90,2); var liuwei= student( "liuwei" ,80,3); var ertuzi= student( "ertuzi" ,85,3); var result=praiseAdd([liming,liyi,liuwei,ertuzi]); for ( var i in result){ console.log( "name:" +i+ ",score:" +result[i]); } |
所以简单的说,其实钩子机制就是利用一张表去匹配,而不是一次次的if条件判断。
Jquery 中使用hook机制的例子
Jquery 中使用hook机制的例子1:
在Jquery 中hook机制被大量的使用,这里我们就Jquery中判断变量类型的type方法来具体看一下
通常我们在js中判断一个变量的数据类型?首先会想到type of 和 instanceof
如果是基本类型我们可以直接使用typeof,但是这种方式只能判断基本数据类型,如果是对象,它返回结果都市Object,如果变量是null它返回的也是Object。这个时候我们要准确的判断一般的写法可能会是:
1 2 3 4 5 6 7 8 9 | function type(obj){ var type = "" ; if (obj== null ){ type = null ; } else { type = obj.a.constructor.toString().split( "(" )[0].split( " " )[1] } return type; } |
在jquery中的实现是:
1 2 3 4 5 6 7 8 9 10 11 | var class2type={}; var toString = Object.prototype.toString; jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol" , function (index,name){ class2type[ "Object" + " name" ]==name.toLowerCase(); }) type: function (obj){ if (obj== null ){ return obj+ "" ; } return typeof obj == "Object" || typeof obj === "function" ?class2type[toString.call(obj)]||| "object" : typeof obj } |
上面代码中
class2type = { ‘[object Boolean]’: ‘boolean’, ‘[object Number]’: ‘number’, ‘[object String]’: ‘string’, ‘[object Function]’: ‘function’, ‘[object Undefined]’: ‘undefined’, ‘[object Null]’: ‘null’, ‘[object Array]’: ‘array’, ‘[object Date]’: ‘date’, ‘[object RegExp]’: ‘regexp’, ‘[object Object]’: ‘object’, ‘[object Error]’: ‘error’};
设置一个类型钩子对象
toString.call(obj)就是Object.prototype.toString.call(arg)来细致判断obj的类型。在这里则转换成对象对应索引是否在class2type 中存在相应value,若存在则返回value判断,若不存在则返回object类型。
这样就实现了类型的判断。
Jquery 中使用hook机制的例子2:
jQuery中大量的使用了钩子机制去做一些兼容。拿$.type方法为例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | ( function (window, undefined) { var // 用于预存储一张类型表用于 hook class2type = {}; // 原生的 typeof 方法并不能区分出一个变量它是 Array 、RegExp 等 object 类型,jQuery 为了扩展 typeof 的表达力,因此有了 $.type 方法 // 针对一些特殊的对象(例如 null,Array,RegExp)也进行精准的类型判断 // 运用了钩子机制,判断类型前,将常见类型打表,先存于一个 Hash 表 class2type 里边 jQuery.each( "Boolean Number String Function Array Date RegExp Object Error" .split( " " ), function (i, name) { class2type[ "[object " + name + "]" ] = name.toLowerCase(); }); jQuery.extend({ // 确定JavaScript 对象的类型 // 这个方法的关键之处在于 class2type[core_toString.call(obj)] // 可以使得 typeof obj 为 "object" 类型的得到更进一步的精确判断 type: function (obj) { if (obj == null ) { return String(obj); } // 利用事先存好的 hash 表 class2type 作精准判断 // 这里因为 hook 的存在,省去了大量的 else if 判断 return typeof obj === "object" || typeof obj === "function" ? class2type[core_toString.call(obj)] || "object" : typeof obj; } }) })(window); |
core_toString是定义了一个空对象,然后保存toString()方法。
1 2 | var core={}; var core_toString=core.toString; |
这样后边就可以直接调用Object.prototype.toString()方法,而不用每次都再去原型链上去找,节约了很多开销,jQuery中做了很多这样的变量保存。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架