jQuery的XX如何实现?——1.框架
源码链接:内附实例代码
jQuery使用许久了,但是有一些API的实现实在想不通。于是抽空看了jQuery源码,现在把学习过程中发现的一些彩蛋介绍给大家(⊙0⊙)。
下面将使用简化的代码来介绍,主要关注jQuery的实现思想~>_<~
1 //匿名立即执行函数 2 //1.防止污染全局空间 3 //2.选择性保护内部变量 4 (function(window, undefined){ 5 //第二参数undefined设置而不传的原因: 6 // 外部发生这种情况:var undefined = 10时,undefined会被篡改 7 // 设置第二参数而不传,则undefined就会被重置回原来值 8 9 function jQuery(sel){ 10 return new jQuery.prototype.init(sel); 11 } 12 13 jQuery.prototype = { 14 constructor: jQuery, 15 init: function(sel){ 16 if(typeof sel === 'string'){ 17 var that = this; 18 //jQuery内部使用的是Sizzle,这里使用querySelectorAll替代 19 var nodeList = document.querySelectorAll(sel); 20 Array.prototype.forEach.call(nodeList, function(val, i){ 21 that[i] = val; 22 }) 23 this.selector = sel; 24 this.length = nodeList.length; 25 } 26 } 27 } 28 29 jQuery.prototype.init.prototype = jQuery.prototype; 30 31 //对外暴露jQuery:将jQuery绑定在window上面 32 window.$ = jQuery; 33 })(window);
--------------------------
jQuery一开始使用匿名立即执行函数包裹其内部,并在第5行对外暴露;
所谓的匿名立即执行函数即这个函数是匿名的(没有名字)、定义完后立即调用的;
当我们在外部调用$("div")时,其实调用的就是内部的jQuery("div");
(function(window, undefined){ //内部变量 //对外暴露jQuery:将jQuery绑定在window上面 window.$ = jQuery; })(window); $("div")
--------------------------
好,接下来稍复杂点,下面的代码主要实现如图的互相引用:
以$('div')调用为例:
从第2行代码可以看出,jQuery使用jQuery.prototype.init来实例化jQuery对象,但这会带来一个问题:
实例化的对象只能访问到init下的变量,而不能访问到jQuery.prototype(jQuery对外提供的API绑定在该对象下)。
于是乎,补写第21行代码,将init.prototype指向jQuery.prototype即可。
这样就完成了,使用init来实例化,且可以在init作用域下访问到jQuery.prototype。
1 function jQuery(sel){ 2 return new jQuery.prototype.init(sel); 3 } 4 5 jQuery.prototype = { 6 constructor: jQuery, 7 init: function(sel){ 8 if(typeof sel === 'string'){ 9 var that = this; 10 //jQuery内部使用的是Sizzle,这里使用querySelectorAll替代 11 var nodeList = document.querySelectorAll(sel); 12 Array.prototype.forEach.call(nodeList, function(val, i){ 13 that[i] = val; 14 }) 15 this.selector = sel; 16 this.length = nodeList.length; 17 } 18 } 19 } 20 21 jQuery.prototype.init.prototype = jQuery.prototype;
为什么使用jQuery.prototype.init来实例化对象,而不直接使用jQuery函数呢?
假设使用jQuery函数来实例化对象,这样对象之间的引用的确可以简化为 jQuery-->jQuery.prototype。
但是调用会变得繁琐起来:new $('div'),所以基于这个考虑(猜测(⊙0⊙)),在内部使用较为复杂的实现,来简化调用。
--------------------------
好,最后,再来看一下init的实现。同样也简化了代码,只实现了最常用的一种情况。
jQuery会把获取到的nodeList处理成数组(方便后续使用),并在其下挂载一些变量,如length,selector。
1 init: function(sel){ 2 if(typeof sel === 'string'){ 3 var that = this; 4 //jQuery内部使用的是Sizzle,这里使用querySelectorAll替代 5 var nodeList = document.querySelectorAll(sel); 6 Array.prototype.forEach.call(nodeList, function(val, i){ 7 that[i] = val; 8 }) 9 this.selector = sel; 10 this.length = nodeList.length; 11 } 12 }
--------------------------
下一期预告:jQuery的XX如何实现?——2.show与链式调用
ps:代码已经上传到github中了
-----------------------------------------
(⊙0⊙)如果该博文有用,记得点个赞哦
转载指明出处即可╰( ̄▽ ̄)╮
欢迎讨论o(≧v≦)o~~
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现