jQuery源码的一个坑
纯吐槽
大半夜也真是够了,想学着jQ造个小轮子巩固下js,结果一开始就卡住了。
虽然之前也看过源码,但是主要是研究方法实现什么的,对于框架主函数和入口结构不怎么熟悉,于是想着一步一步调试看看。
$('#div')
简单吧,为了方便调试看过程,直接调用选择符,而且是一个ID,可以快速匹配调用原生方法。
大概流程是这样的。
var
version = "3.1.1", // Define a local copy of jQuery
jQuery = function(selector, context) { // The jQuery object is actually just the init constructor 'enhanced'
// Need init if jQuery is called (just allow error to be thrown if not included)
return new jQuery.fn.init(selector, context);
},
首先,如我所料进入了主函数,然后调用了new准备构造出一个对象(目的是为了应对奇怪的参数导致错误)。
//一号坑 没注意到缩写
init = jQuery.fn.init = function(selector, context, root) {
var match, elem; // HANDLE: $(""), $(null), $(undefined), $(false)
if (!selector) {
return this;
}
//...
}
然后,进入了初始化函数,jQ有很多地方多缩写了,比如说jQuery.fn=jQuery.prototype,这里也缩写,当时没注意。
一般情况会进入Sizzle引擎,但是因为用的ID,比较简单,提前返回。返回的是一个'jQuery'对象,里面包含一个DOM节点,原型有大量的方法。(这里一定要加上引号)
好,开始学着造轮子。
//入口函数
var jimmy = function(ele) {
return new jimmy.prototype.init(ele);
}; //是要简化一下
jimmy.fn = jimmy.prototype; //超简单扩展函数
jimmy.fn.extend = function(o1, o2) {
for (var key in o1) {
this[key] = o1[key];
}
return this;
}; //初始化
jimmy.fn.init = function(ele, ctx) {
ele = rquickExpr.exec(ele);
return this;
}
其中有段代码大概是这样子,反正我又不做兼容,问题出现了!我的jimmy对象原型,啥方法都没有,准备用来扩展的extend也没有。
我就照着之前的调试又跑了一遍,还在函数中添加了多个console.log。结果发现jQuery源码在进入初始化函数中,this指向的是jQuery.init.prototype,这个理论上是没问题的,毕竟new出一个对象,默认就是这样的,接着函数中直接返回了this。
对着控制台我就看到了这个jQuery对象是这个样子的,jQuery.fn.init[1]。WTK!说好的jQuery对象呢?怎么是jQuery原型的初始化对象?我可能初始化了一个假的jQuery对象。。。接着点开了__proto__属性,刷的一下方法就出来了。这???也就是说方法是定义在jQuery.fn.init.__proto__上的。
回头又翻了下jQuery的扩展函数extend,发现貌似是普通的拷贝,并没有对this做特殊处理。也就是说,原型方法还是在jQuery原型上。那为什么方法怎么跑到jQuery原型方法的原型上的???
我一行一行的看代码,直到我发现这么一条语句。
// Give the init function the jQuery prototype for later instantiation
init.prototype = jQuery.fn;
恩,对的,在后面代码的某一行中,出现了这么一条语句,就像两个高手进行结拜一样,这两玩意的原形应该是这样的。
jQuery.prototype.init.prototype = jQuery.prototype
这条语句确实挺恶心的,但是更恶心的是放源码中间,还加了一句注释:将jQuery原型给init函数方便后面初始化。
后面你妹啊!初始化语句全在前面好不!恩,好吧,英文博大精深,应该是说方便jQuery之后执行初始化。
总之,我一晚上的时间都献给了这句代码,虽然弄明白了初始化,但是总感觉被作者耍了,还是尤大的vue好,即使看不懂也不会碰到隐藏的'宝藏'。
完结撒花
jQuery源码的一个坑的更多相关文章
- js便签笔记(9)——解读jquery源码时记录的一些知识点
近来一直利用业余时间在看jquery2.1.1源码,大约看了两千行了.平时看的时候,做了一些笔记,贴出来分享. 1. Array.prototype.slice.call 可以将伪数组转化为真正的数组 ...
- 车大棒浅谈jQuery源码(一)
背景 因为最近辞职找工作,投了许多家公司.结果简历要么石沉大海,一点音讯都没有,要么就是邮件回复说不匹配.后面加了一些QQ群,才发现原来我工作经验年限太少了.现在深圳都是3经验起步,北京据说更加恐怖. ...
- jQuery源码学习感想
还记得去年(2015)九月份的时候,作为一个大四的学生去参加美团霸面,结果被美团技术总监教育了一番,那次问了我很多jQuery源码的知识点,以前虽然喜欢研究框架,但水平还不足够来研究jQuery源码, ...
- Jquery源码学习(第一天)
jQuery是面向对象的设计通过window.$ = window.jQuery = $; 向外提供接口,将$挂在window下,外部就可以使用$和jQuery $("#div1" ...
- jQuery源码分析系列(38) : 队列操作
Queue队列,如同data数据缓存与Deferred异步模型一样,都是jQuery库的内部实现的基础设施 Queue队列是animate动画依赖的基础设施,整个jQuery中队列仅供给动画使用 Qu ...
- jQuery源码 Ajax模块分析
写在前面: 先讲讲ajax中的相关函数,然后结合函数功能来具体分析源代码. 相关函数: >>ajax全局事件处理程序 .ajaxStart(handler) 注册一个ajaxStart事件 ...
- jQuery源码:从原理到实战
jQuery源码:从原理到实战 jQuery选择器对象 $(".my-class"); document.querySelectorAll*".my-class" ...
- 【菜鸟学习jquery源码】数据缓存与data()
前言 最近比较烦,深圳的工作还没着落,论文不想弄,烦.....今天看了下jquery的数据缓存的代码,参考着Aaron的源码分析,自己有点理解了,和大家分享下.以后也打算把自己的jquery的学习心得 ...
- 从jquery源码中看类型判断和数组的一些操作
在深入看jquery源码中,大家会发现源码写的相当巧妙.那我今天也通过几个源码中用到的技巧来抛砖引玉,希望大家能共同研究源码之精华,不要囫囵吞枣. 1.将类数组转化成数组 我想大家首先想到的方法是fo ...
随机推荐
- Javascript-正则表达式-开发中的使用.
-- "(-1~99)之间 -1表示无限次!" pattern="^((-1)|([0-9]{0,2}))$" -- "(0~99.99)之间 的金额 ...
- 浅谈Linux虚拟内存
我的orangepi内存很少,所以我打算给它弄个虚拟内存 首先建立一个1G的空文件: dd if=/dev/zero of=/home/swapfile bs=64M count=16 格式化为swa ...
- 用reduce实现阶乘计算
def fact(a,b): return a*b from functools import reduce print(reduce(fact,range(1,6))) from functools ...
- C3P0 WARN: Establishing SSL connection without server's identity verification is not recommended
c3p0的出现,是为了大大提高应用程序和数据库之间访问效率的. 它的特性: 编码的简单易用 连接的复用 连接的管理 今天在配置C3p0的时候出现了这个warn 原因是因为要验证SSL Wed Se ...
- [python学习笔记] String格式化
格式化 S % (args...) 方式 特点 str里的占位符同java里的占位符. 优势 这种方式可以限定格式化的时候接受的数据类型. 常见占位符 %d 接收数字,格式化为 十进制 %x 接收数字 ...
- Matlab入门学习(文件读写)
一.save,load >> a=[ ]; >> b=[ ] b = >> save('b.mat','a','b');%a file named b.mat wi ...
- Opengl4.5 中文手册—D
索引 A B C D E F G H I J K L M N O P Q ...
- eclipse中搜狗输入法中文状态下输出的全是英文
在eclipse中搜狗输入法变成了如图这样 在中文状态下,提示的全是中文. 查询到的解决方案: 快捷键ctrl+shift+E关闭搜狗智能英文.然而与eclipse中 Ctrl+shift+E 快捷键 ...
- java核心卷轴之泛型程序设计
本文根据<Java核心卷轴>第十二章总结而来,更加详细的内容请查看<Java核心卷轴> 1. 泛型类型只能是引用类型,不可以使用基本数据类型. 2. 类型变量含义 E : 集合 ...
- 醒醒吧!互联网的真正未来不是AI,更不是VR,AR,而是区块链
这些力量并非命运,而是轨迹.他们提供的并不是我们将去向何方的预测,而是告诉我们,在不远的将来,我们会向那个方向前行,必然而然. ---凯文•凯利 文字与货币 人类在演化过程中,凭借智慧创造了无数事物, ...