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 ...
随机推荐
- Mybatis学习(三)XML配置文件之mybatis-config.xml
1.MyBatis的配置文件结构 1.1 properties 这些是外部化的,可替代的属性,这些属性也可以配置在典型的 Java 属性配置文件中,或者通过 properties 元素的子元素来传递. ...
- 在有main函数的前提下 eclipse找不到主类
有时候在测试类的时候eclipse会莫名奇妙的提示找不到主类 接下来分别有几种解决办法 1.在项目上右击> Builder Path -> Configure Build Path - ...
- openGPS.cn - 高精度IP定位原理,定位误差说明
[ip定位历史] 关于IP定位,最早是通过运营商实现,每个运营商申请到的ip段,在某个范围内使用. 因此早期只能是国家为单位的基础数据. 对于比较大的国家,就进一步划分,比如,中国某通讯公司(不打广告 ...
- BZOJ1854_游戏_KEY
1854: [Scoi2010]游戏 Time Limit: 5 Sec Memory Limit: 162 MB Description lxhgww最近迷上了一款游戏,在游戏里,他拥有很多的装备, ...
- 在asp.net web api 2 使用 Serilog 记录日志
Serilog是.net里面非常不错的记录日志的库,另外一个我认为比较好的Log库是NLog. 在我个人的asp.net web api 2 基础框架(Github地址)里,我原来使用的是NLog,但 ...
- Java并发(一、概述)
离上次写博客又隔了很久,心中有愧.在我不断使用Java的过程中,几乎都是拿来就用,就Java并发这块我还没有系统的梳理过,趁着国庆有空余时间,把它梳理一遍.以下部分内容参考相关书籍,以作学习之用,特此 ...
- JS双击div编辑文本内容
HTML代码: <div class="album"> <div class="image"><a href="java ...
- Elixir游戏服设计五
在<Elixir游戏服设计一>里提到,按照系统功能划分成app要保证原子性很难, 现在想想也没那么难.保证原子性,无非就是需要某个单点去完成操作.那么选择玩家进程去做原子性工作就可以了. ...
- 在不用Promise的情况下如何控制异步请求?
如何更好的控制异步请求?相信大家一定首选Promise对象.确实,使用Promise控制异步请求确实非常方便,直接使用then()方法就可以实现当一个异步请求完成后再处理另一个请求或操作.同时,这样的 ...
- 1、Http概述
1.1 Web客户端和服务器 HTTP 客户端和 HTTP 服务器共同构成了万维网的基本组件,客户端向服务器发送 HTTP 请求, 服务器会在 HTTP 响应中回送所请求的数据. 示意图: 1.2 媒 ...