jQuery对象是使用构造函数和原型模式相结合的方式创建的。现在来看看jQuery的原型对象jQuery.prototype:

 jQuery.fn = jQuery.prototype = {
//成员变量和方法
}

这里给原型对象起了一个别名叫做jQuery.fn。要注意的是这个jQuery.fn可不是jQuery对象的属性,而是jQuery构造方法本身的属性,它是不会传给它所创建的对象的。如果你在控制台敲$().fn的话输出的结果会是undefined。接下来看看原型对象里面有些什么:

 jquery: "2.1.1",

 constructor: jQuery,

jquery:在原型对象中,先定义了jquery属性来标识版本信息,这里是2.1.1版。在我们写代码的时候可以通过查看这个属性判断对象是不是jQuery对象。

constructor:这个属性在低版本的jQuery代码中是没有的(例如远古的1.2.6版本)。在这里我能看见这个属性我真的觉得现在的jQuery成熟了。每一个对象都有一个constructor属性,是由创建它的构造函数的原型对象传递而来,指向了创建它的构造方法。也就是如果你在chrome的控制台敲:

 var obj = {};

 obj.constructor;

控制台会显示:

  function Object() { [native code] }

构造函数的原型是在定义构造函数的时候自动生成,其中的constructor会自动指向该构造函数。也就是你在输入:

 function Obj(){}

 Obj.prototype.constructor

控制台会输出:

  function Obj(){}

现在回过头我们再来看看jQuery的代码。定义jQuery.prototype时:

 jQuery.fn = jQuery.prototype = {
//成员变量和方法
}

这里的过程其实是新建一个对象,然后将jQuery.prototype指向这个新建的对象。而这时新建对象因为是由function Object(){}方法构建的。所以它的constructor属性其实是指向的function Object(){}方法。进而导致所有由jQuery方法创建的对象的constructor也是指向的

function Object(){}方法。这里重新定义jQuery.prototype.constructor属性,让它重新指向jQuery构造函数。平常我们在使用jQuery的时候也许永远也不会用到constructor这个属性,但是这种小细节的完善无疑让整个代码变得严谨很多。

继续往下看代码:

 // Start with an empty selector
selector: "", // The default length of a jQuery object is 0
length: 0,

selector:这个属性指的是默认的选择器。

length:jQuery对象其实是一个类数组对象。什么叫类数组对象?我的理解是它不是一个数组,而是一个对象但是当我们访问它的数据时某些表现形式跟数组很相似,比如可以用[0]、[1]....[n]来访问数据,可以用length来获取数据的数目。jQuery就是一种类数组对象通过选择器选择页面dom元素,并以jq[0]、jq[1]、jq[2]...、jq[n]的形式将个元素存储在jQuery对象中,这个length属性就是用来记录元素个数。

继续往下:

 var arr = [];

 var slice = arr.slice;

 toArray: function() {
return slice.call(this);
},

toArray:这个方法是将jQuery对象转化为一个数组(是真正的数组哦)。我们知道数组的

slice(start,end)

方法可从已有的数组中返回选定的元素而不破坏原有的数组,当参数不填的时候就返回这个数组的一个副本。因为jQuery对象是类数组对象,所以这里直接将数组arr中slice的对象上下文换成当前jQuery对象(不知道这个对象上下文能不能理解成作用域哈,不过this肯定是指的新对象啦)。slice函数执行后返回一个真正的js数组,里面的元素就是jQuery对象中的各个dom元素,但是又不破坏原来的jQuery对象,这一招真的挺不错,一行代码使用现有的资源解决了很多事情,这种思路要多学习。不过slice的调用我们还可以用

Array.prototype.slice.call(this)

这种方式调用也是可以的,不用特意新建一个对象。

往下:

 get: function(num) {
return num != null ? // Return just the one element from the set
(num < 0 ? this[num + this.length] : this[num]) : // Return all the elements in a clean array
slice.call(this);
},

get:这个方法感觉根据传参不同会有两个功能。一个是如果传参num不为空的话,那么根据num返回jQuery对象中的相应dom元素。另一个就是当num为空得时候将jQuery对象转换为数组。所以我一直很奇怪为啥有了get方法还要专门写一个toArray方法,希望有大大为我解惑。

咱们继续:

 pushStack: function(elems) {

     // Build a new jQuery matched element set
//jQuery.merge:合并两个数组的内容到第一个数组中
var ret = jQuery.merge(this.constructor(), elems); // Add the old object onto the stack (as a reference)
ret.prevObject = this;
ret.context = this.context; // Return the newly-formed element set
return ret;
},

pushStack:大家都知道当我们使用jQuery选择区创建jQuery对象后,例如$(".class"),还可以使用jq.find、jq.filter等方法进一步处理,返回新的jQuery对象。但是这样往往会对旧的jQuery产生“破坏”性德影响,因为它们会修改匹配元素的集合(在jQuery中被称为matched element set)所以jQuery在进行这种“破坏性”的操作之前就会调用pushStack方法将现有的匹配元素集合暂时保存起来。

首先调用jQuery.merge方法,它将两个数组合并到第一个数组中。不过我觉得很有意思的是两个传参:

第一个参数this.constructor指的是jQuery构造方法原型对象中的constructor属性,这个前面说过。的this.constructor()指的是调用jQuery构造方法构建一个新对象,如同$()一样。因为jQuery是类数组对象所以也可以充当merge的传参。我觉得很炫酷的是这里创建新jQuery的写法,要是我本人的话我肯定会直接用jQuery()这么写了。

第二个参数elems就是pushStack传进来的参数了,它可以是真正的数组,也可以是类数组对象。通过merge方法,可以将elems转化为一个jQuery对象。

接下来就很简单了,将当前对象用ret.prevObject保存起来,值得一提的是这里还专门用了一个ret.context来保存当前jQuery对象的选择器上下文,就是使用选择器匹配元素时第二个参数,eg:$("div",document.getElementById("id"))。我查了一下w3c.school,context 属性在 jQuery version 1.10 中被弃用,但是高版本的jQuery中还能看到这个,所以我也不知道到底怎么回事。

不过既然说到jQuery.merge了那干脆来看看它吧:

 merge: function(first, second) {
var len = +second.length,
j = 0,
i = first.length; for (; j < len; j++) {
first[i++] = second[j];
} first.length = i; return first;
},

具体代码就不细说了~~~没什么技术含量,值得一提的是从merge的代码上看好像并没有去重的功能。这里的去重不仅仅是重复数字什么的,更包含重复的元素。比方说:

 var arr1 = [], arr2 = [];

 var ele = document.getElementById("id");

 arr1.push(ele);
arr2.push(ele); var arr3 = jQuery.merge(arr1, arr2);

运行后arr3.length将会是2虽然两个元素其实是同一个dom对象的引用。

菜鸟的jQuery源码学习笔记(二)的更多相关文章

  1. 菜鸟的jQuery源码学习笔记(前言)

    前言 相信任何一名前端开发人员或者是前端爱好者都对jQuery不陌生.jQuery简单易用,功能强大,特别是拥有良好的浏览器兼容性,大大降低了前端开发的难度,使得前端开发变得“平易近人起来”.自从本人 ...

  2. jquery源码学习笔记二:jQuery工厂

    笔记一里记录,jQuery的总体结构如下: (function( global, factory ) { //调用factory(工厂)生成jQuery实例 factory( global ); }( ...

  3. jQuery源码学习笔记二

    //添加实例属性和方法 jQuery.fn = jQuery.prototype = { // 版本,使用方式:$().jquery弹出当前引入的jquery的版本 jquery: core_vers ...

  4. 菜鸟的jQuery源码学习笔记(一)

    整个jQuery是一个自调用的匿名函数: (function(global, factory) { if (typeof module === "object" && ...

  5. 菜鸟的jQuery源码学习笔记(三)

    each: function(callback, args) { return jQuery.each(this, callback, args); }, each:这个调用了jQuery.each方 ...

  6. jquery源码学习笔记三:jQuery工厂剖析

    jquery源码学习笔记二:jQuery工厂 jquery源码学习笔记一:总体结构 上两篇说过,query的核心是一个jQuery工厂.其代码如下 function( window, noGlobal ...

  7. jQuery源码学习笔记一

    学习jQuery源码,我主要是通过妙味视频上学习的.这里将所有的源码分析,还有一些自己弄懂过程中的方法及示例整理出来,供大家参考. 我用的jquery v2.0.3版本. var rootjQuery ...

  8. jquery源码学习笔记(一)jQuery的无new构建

    本人是一名.net程序员..... 你一个.net coder 看什么jQuery 源码啊? 原因吗,很简单.技多不压身吗(麻蛋,前端工作好高...羡慕). 我一直都很喜欢JavaScript,废话不 ...

  9. jquery源码学习笔记一:总体结构

    练武不练功,到老一场空.计算机也一样. 计算机的功,就是原理.如果程序员只会使用各种函数,各种框架,而不知其原理,顶多熟练工人而已.知其然,更要知其所以然. jquery我们用得很爽,但它究竟咋实现的 ...

随机推荐

  1. [置顶] 【C/C++学习】之十三、虚函数剖析

    所谓虚函数,虚就虚在“推迟联编”或者“动态联编”上,一个类函数的调用并不是在编译时刻被确定的,而是在运行时刻被确定的.由于编写代码的时候并不能确定被调用的是基类的函数还是哪个派生类的函数,所以被称为“ ...

  2. 海量数据面试题----分而治之/hash映射 + hash统计 + 堆/快速/归并排序

    1.从set/map谈到hashtable/hash_map/hash_set 稍后本文第二部分中将多次提到hash_map/hash_set,下面稍稍介绍下这些容器,以作为基础准备.一般来说,STL ...

  3. html css 笔记

    cursor其他取值 鼠标移入    auto          :标准光标    default        :标准箭头    pointer        :手形光标    wait       ...

  4. js阻止事件冒泡的方法

    /********************************************js方法*************************************************** ...

  5. 利用树莓派跑python爬虫的简单教程——从无到有

    因为学校项目的原因入手了树莓派,到手先折腾了两天,发现网上的教程大都是拿他搭建服务器,mail,或者媒体服务器之类,对于在学校限时的宽带来说有点不太现实,不过低功耗适合一直开着的确启发了我.所以想到拿 ...

  6. MyEclipse6.5安装SVN插件的三种方法

    MyEclipse6.5安装SVN插件的三种方法 方法一.如果可以上网可在线安装 1. 打开Myeclipse,在菜单栏中选择Help→Software Updates→Find and Instal ...

  7. WPF 资源收集

    转载地址:http://www.cnblogs.com/zhoujg/archive/2009/11/04/1596195.html OpenExpressApp的UI现在是使用WPF,所以熟悉WPF ...

  8. USB系列之六:基于DOSUSB的简单U盘驱动程序

    首先要说明的是,该驱动程序仅实现了部分块设备的功能,如果作为成品软件使用,会感觉性能比较差,而且有些功能(比如FORMAT)是不能完成的,发表此驱动程序的目的旨在说明USB的编程原理以及DOS下驱动程 ...

  9. Delphi之通过代码示例学习XML解析、StringReplace的用法(异常控制 good)

    *Delphi之通过代码示例学习XML解析.StringReplace的用法 这个程序可以用于解析任何合法的XML字符串. 首先是看一下程序的运行效果: 以解析这样一个XML的字符串为例: <? ...

  10. 基于 Bootstrap 的扁平化 UI 开发包

    Flat UI是一款基于Bootstrap的扁平化前端UI工具包,Flat UI的组件外观设计非常清新和漂亮,Flat UI的组件包含按钮,输入框,组合按钮,复选框,单选按钮,标签,菜单,进度条和滑块 ...