纯吐槽

  大半夜也真是够了,想学着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源码的一个坑的更多相关文章

  1. js便签笔记(9)——解读jquery源码时记录的一些知识点

    近来一直利用业余时间在看jquery2.1.1源码,大约看了两千行了.平时看的时候,做了一些笔记,贴出来分享. 1. Array.prototype.slice.call 可以将伪数组转化为真正的数组 ...

  2. 车大棒浅谈jQuery源码(一)

    背景 因为最近辞职找工作,投了许多家公司.结果简历要么石沉大海,一点音讯都没有,要么就是邮件回复说不匹配.后面加了一些QQ群,才发现原来我工作经验年限太少了.现在深圳都是3经验起步,北京据说更加恐怖. ...

  3. jQuery源码学习感想

    还记得去年(2015)九月份的时候,作为一个大四的学生去参加美团霸面,结果被美团技术总监教育了一番,那次问了我很多jQuery源码的知识点,以前虽然喜欢研究框架,但水平还不足够来研究jQuery源码, ...

  4. Jquery源码学习(第一天)

    jQuery是面向对象的设计通过window.$ = window.jQuery = $; 向外提供接口,将$挂在window下,外部就可以使用$和jQuery $("#div1" ...

  5. jQuery源码分析系列(38) : 队列操作

    Queue队列,如同data数据缓存与Deferred异步模型一样,都是jQuery库的内部实现的基础设施 Queue队列是animate动画依赖的基础设施,整个jQuery中队列仅供给动画使用 Qu ...

  6. jQuery源码 Ajax模块分析

    写在前面: 先讲讲ajax中的相关函数,然后结合函数功能来具体分析源代码. 相关函数: >>ajax全局事件处理程序 .ajaxStart(handler) 注册一个ajaxStart事件 ...

  7. jQuery源码:从原理到实战

    jQuery源码:从原理到实战 jQuery选择器对象 $(".my-class"); document.querySelectorAll*".my-class" ...

  8. 【菜鸟学习jquery源码】数据缓存与data()

    前言 最近比较烦,深圳的工作还没着落,论文不想弄,烦.....今天看了下jquery的数据缓存的代码,参考着Aaron的源码分析,自己有点理解了,和大家分享下.以后也打算把自己的jquery的学习心得 ...

  9. 从jquery源码中看类型判断和数组的一些操作

    在深入看jquery源码中,大家会发现源码写的相当巧妙.那我今天也通过几个源码中用到的技巧来抛砖引玉,希望大家能共同研究源码之精华,不要囫囵吞枣. 1.将类数组转化成数组 我想大家首先想到的方法是fo ...

随机推荐

  1. Python学习笔记013_正则表达式

    Python中的正则表达式是通过 re 模块实现的. 通配符 .  表示除了换行以外的任何字符; 编写正则表达式时使用  r're'  , r + 正则表达式内容 >>> impor ...

  2. Ant-打增量包

    如何打增量包具体用法见如下百度网盘的文档. http://pan.baidu.com/s/1gd5pAp1 1, ant 打源码增量包 build_incremental_src.xml 内容如下: ...

  3. [UIKit学习]01.关于UIView,frame,bounds,center

    UIView是Cocoa大多控件的父类,本身不带事件. UIView的常见用法 @property(nonatomic,readonly) UIView *superview; 获得自己的父控件对象 ...

  4. [AHOI2001]彩票摇奖

    [AHOI2001]彩票摇奖 题目描述 为了丰富人民群众的生活.支持某些社会公益事业,北塔市设置了一 项彩票.该彩票的规则是: (1) 每张彩票上印有 7 个各不相同的号码,且这些号码的取指范围为 1 ...

  5. windows 结束进程的详细过程

    windows上如何结束进程的详细过程,下面附详细,图文说明 在cmd下,输入  netstat   -ano|findstr  8080      //说明:查看占用8080端口的进程 在cmd下, ...

  6. 深入理解String的关键点和方法

    String是Java开发中最最常见的,本篇博客针对String的原理和常用的方法,以及String的在开发中常见问题做一个整体性的概括整理.因为之前对String的特性做过一些分析,所以不在详细描述 ...

  7. Hadoop安全(2)——————UserGroupInformation

    UserGroupInformation保存hadoop用户及组信息 此类包装JAAS Subject,并提供确定用户的用户名和组的方法.它支持Windows,Unix和Kerberos登录模块.

  8. Redis 的安装与使用

    环境:CentOS 6.6 Redis 版本:redis-3.0 (考虑到 Redis3.0 在集群和性能提升方面的特性,rc 版为正式版的候选版,而且很快就出正式版) 安装目录:/usr/local ...

  9. python之路第五篇之装饰器:(进阶篇)

    装饰器: 学前必备知识: def f1(): print "f1" f1() #表示函数执行 f1 #表示函数,指向内存地址 f1 = lambda x: x + 1 f1() # ...

  10. 第9期Unity User Group Beijing图文报道:《Unity实战经验分享》

    时间来到了金秋九月,北京UUG活动也来到了第九期.本次活动的主题为<Unity实战经验分享>,为此我们邀请了3位资深的行业大神.这次我们仍然在北京市海淀区丹棱街5号微软大厦举行活动,在这里 ...