jQuery源码学习(1):整体架构
整体架构
$().find().css().hide()
从jQuery的表达式可以看出两点:
- jQuery的构建方式
 - jQuery的调用方式
 
下面从这两方面来窥探jQuery的整体架构:
分析一:无new构建
这一点是推测jQ构建方式的重点。既然没有使用new,jQ必定在函数中返回了一个实例,也就是通过工厂模式来创建对象。
var aQuery = function(select){
  var o = new Object();
  o.select = select;
  o.myFunc = function(){};
}
然而这种方法显然非常笨拙,每次新建一个对象实例都必须声明其所有共用方法。能不能把构造函数与原型模式融入到这里面来呢?
var aQuery = function(selector){
  return aQuery.prototype.init(selector);
};
aQuery.prototype = {                                  // aQuery的原型
  init: function(selector){                  // init作为新的构造函数
    this.selector = selector;
    return this;
  },
  myFunc: function(){}
};
console.log(aQuery('s1'));
代码运行之后,在控制台显示的是下面这样的结果:
{
  init: [Function],
  myFunc: [Function],
  selector: 's1'
}
this指向了aQuery的原型对象,并且共用了所有方法。然而这里面的陷阱在于,由于我们并没有new一个新对象,所以构造函数内部的this指向了aQuery的原型,共享了本应该私有的属性。
var a1 = aQuery('s1');
var a2 = aQuery('s2');
console.log(a1.selector);      // s2
那么是不是只要返回一个新实例就可以了呢?
var aQuery = function(selector, context){
  return (new aQuery.prototype.init(selector, context));
};
aQuery.prototype = {...};
var a1 = aQuery('s1');
var a2 = aQuery('s2');
console.log(a1.selector);      // s1
console.log(a1);         //{ selector: 's1' }   myFunc不见了!
由上可见,new关键字新建了一个空对象,使构造函数内部的this指向该对象,解决了属性公有的问题(这部分知识点请参考Javascript对象部分)。然而同时,也丢失了aQuery.prototype。那么jQuery是怎么解决这个问题的呢?这就是jQuery构建方法的关键所在:原型传递。
直接上代码:
var aQuery = function(selector){
  return (new aQuery.prototype.init(selector));
};
aQuery.prototype = {                                  // aQuery的原型
  init: function(selector){                  // init作为新的构造函数
    this.selector = selector;
    return this;
  },
  myFunc: function(){
    return "aQuery.func";
  }
};
aQuery.prototype.init.prototype = aQuery.prototype;
var a1 = aQuery('s1');
var a2 = aQuery('s2');
console.log(a1.selector);      // s1
console.log(a1.myFunc());      // aQuery.func
其实本质上讲,init构建出来的这个对象,就是jQuery对象。
这样,我们总算理清了jQuery无new构建的原理。使用工厂模式返回一个实例,并将该实例构造函数的原型指向aQuery原型本身,实现了私有属性和共有方法。

各中关系如图所示,其中fn指代了jQuery的原型对象。
分析二:链式调用
当使用了new关键字后,jQuery的所有方法中的this都指向了新建的实例,所以我们只要在方法最后返回this,就可以实现链式调用。然而:
摘自Aaron的JQ源码分析:
最糟糕的是所有对象的方法返回的都是对象本身,也就是说没有返回值,这不一定在任何环境下都适合。
Javascript是无阻塞语言,所以他不是没阻塞,而是不能阻塞,所以他需要通过事件来驱动,异步来完成一些本需要阻塞进程的操作,这样处理只是同步链式,异步链式jquery从1.5开始就引入了Promise,jQuery.Deferred后期在讨论。
jQuery源码学习(1):整体架构的更多相关文章
- spring源码学习——spring整体架构和设计理念
		
Spring是在Rod Johnson的<Expert One-On-One J2EE Development and Design >的基础上衍生而来的.主要目的是通过使用基本的java ...
 - Mybatis源码学习之整体架构(一)
		
简述 关于ORM的定义,我们引用了一下百度百科给出的定义,总体来说ORM就是提供给开发人员API,方便操作关系型数据库的,封装了对数据库操作的过程,同时提供对象与数据之间的映射功能,解放了开发人员对访 ...
 - jQuery源码分析系列 : 整体架构
		
query这么多年了分析都写烂了,老早以前就拜读过, 不过这几年都是做移动端,一直御用zepto, 最近抽出点时间把jquery又给扫一遍 我也不会照本宣科的翻译源码,结合自己的实际经验一起拜读吧! ...
 - 读艾伦的jQuery的无new构建,疑惑分析——jquery源码学习一
		
背景: 有心学习jquery源码,苦于自己水平有限,若自己研究,耗时耗力,且读懂之日无期. 所以,网上寻找高手的源码分析.再经过自己思考,整理,验证.以求有所收获. 此篇为读高手艾伦<jQuer ...
 - jquery源码学习笔记三:jQuery工厂剖析
		
jquery源码学习笔记二:jQuery工厂 jquery源码学习笔记一:总体结构 上两篇说过,query的核心是一个jQuery工厂.其代码如下 function( window, noGlobal ...
 - jquery源码学习(一)——jquery结构概述以及如何合适的暴露全局变量
		
jQuery 源码学习是对js的能力提升很有帮助的一个方法,废话不说,我们来开始学习啦 我们学习的源码是jquery-2.0.3已经不支持IE6,7,8了,因为可以少学很多hack和兼容的方法. jq ...
 - jquery 源码学习(一)
		
从上边的注释看,jQuery的源码结构相当清晰.条理,不像代码那般晦涩和让人纠结 1. 总体架构 1.1 自调用匿名函数 self-invoking anonymous function 打开jQ ...
 - jQuery源码学习感想
		
还记得去年(2015)九月份的时候,作为一个大四的学生去参加美团霸面,结果被美团技术总监教育了一番,那次问了我很多jQuery源码的知识点,以前虽然喜欢研究框架,但水平还不足够来研究jQuery源码, ...
 - jQuery源码分析之整体框架
		
之前只是知道jQuery怎么使用,但是我觉得有必要认真的阅读一下这个库,在分析jQuery源码之前,很有必要对整个jQuery有个整体的框架概念,才能方便后面对jQuery源码的分析和学习,以下是我总 ...
 - jQuery源码分析-01总体架构
		
1. 总体架构 1.1自调用匿名函数 self-invoking anonymous function 打开jQuery源码,首先你会看到这样的代码结构: (function( window, und ...
 
随机推荐
- AngularJS 基础用法
			
判断语句: <li ng-repeat=”person in persons”> <span ng-switch on=”person.sex”> <span ng-sw ...
 - java 基础的几种算法
			
1:冒泡排序:2个之间进行循环筛选 public void sort(int[] a) { int temp = 0; for (int i = a.length - 1; i > 0; i ...
 - 在线的代码托管平台 coding.net ===中国扩展版github
			
coding.net 是国内新兴的一个项目管理平台,功能主要包括:代码托管.在线运行环境.监控代码质量,兼有一定的社交功能. 在线运行环境支持Java.Ruby.Node.js.PHP.Python. ...
 - C#实现http断点下载
			
我们寄希望于万能的解决方案,但是现实的情况总是很糟糕.在软件编程的世界中,技术分散的情况尤为严重,且不说各种语言拥有的优势不能融合,单就一门语言而言,就拥有众多的技术和相关技术需要学习.网络编程就是这 ...
 - Tomcat的class加载的优先顺序
			
Tomcat的class加载的优先顺序一览 1.最先是$JAVA_HOME/jre/lib/ext/下的jar文件. 2.环境变量CLASSPATH中的jar和class文件. 3.$CATALINA ...
 - test命令
			
每一种条件语句的基础都是判断什么是真什么是假.是否了解其工作原理将决定您编写的是质量一般的脚本还是您将引以为荣的脚本.Shell 脚本的能力时常被低估,但实际上其能力的发挥受制于脚本撰写者的能力.您了 ...
 - css盒子
			
<html><head lang="en"> <meta charset="UTF-8"> <title>< ...
 - 关于Application.Lock…Application.Unlock有什么作用?
			
因为Application变量里一般存储的是供所有连接到服务器的用户共享的信息(就像程序中所说的 "全局变量 "), 由于是全局变量,所以就容易出现两个或者多个用户同时对这一变量进 ...
 - Divisor Summation_
			
Divisor Summation Problem Description Give a natural number n (1 <= n <= 500000), please tell ...
 - FZU Problem 2150 Fire Game(bfs)
			
这个题真要好好说一下了,比赛的时候怎么过都过不了,压点总是出错(vis应该初始化为inf,但是我初始化成了-1....),wa了n次,后来想到完全可以避免这个问题,只要入队列的时候判断一下就行了. 由 ...