// 建立方法实例,提高方法访问的速度(避免在原型链上搜索)

 var deletedIds = [];
var slice = deletedIds.slice;
var concat = deletedIds.concat;
var push = deletedIds.push;
var indexOf = deletedIds.indexOf;
var class2type = {};
var toString = class2type.toString;
var hasOwn = class2type.hasOwnProperty;
var support = {}; jQuery.fn = jQuery.prototype = {
// 保存目前jQuery版本号
jquery: version,
// 指向构造器
constructor: jQuery, // 初始化空的选择器
selector: "", // 初始化长度为0,及空的jQuery对象的length为0,可以此判断是否存在查找结果
length: 0,
// 转换成Array并返回
toArray: function() {
return slice.call( this ); // 使用了Array.slice
}, // num == 0 则返回所有元素 // 如果 num < 0, 则返回第this.length + num个元素
get: function( num ) {
return num != null ?
// 返回一个元素
( num < 0 ? this[ num + this.length ] : this[ num ] ) :
// 返回全部元素
slice.call( this );
}, // 将一个DOM元素集Array压入到jQuery栈 // 该方法在find,parent,filter中被频繁使用 // 通过创建prevObject,能够跟踪链式调用中上一个调用方法返回的元素集
pushStack: function( elems ) {
// 建立新的jQuery对象以保存新的元素集(将新元素集合并到其中)
var ret = jQuery.merge( this.constructor(), elems );
// 新jQuery对象中创建prevObject,引用原来的jQuery对象,更新新元素集的上下文
ret.prevObject = this;
ret.context = this.context;
// 返回新的元素集
return ret;
}, // 每个元素都调用一次回调函数,参数已Array形式传递(内部调用时才使用)
each: function( callback, args ) {
return jQuery.each( this, callback, args );
},
// jQuery.map对this中的每个key重新用回调函数计算出新的值并返回 // 将jQuery.map的返回结果添加到新的jQuery中并返回,新的jQuery以原有的元素为基础
map: function( callback ) { return this.pushStack( jQuery.map(this, function( elem, i ) {
return callback.call( elem, i, elem );
}));
},
// 通过slice将"参数数组"截取并压栈
slice: function() {
return this.pushStack( slice.apply( this, arguments ) );
},
// 将第一个元素压栈并返回新的jQuery栈
first: function() {
return this.eq( 0 );
},
// 将最后一个元素压栈并返回新的jQuery栈
last: function() {
return this.eq( -1 ); // 实际上是 len - 1, 即最后一个元素
},
// 取this[i]并压栈,如果i < 0则取this[len + i],如果i > len, 压入空Array
eq: function( i ) {
var len = this.length,
j = +i + ( i < 0 ? len : 0 ); return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );
},
// prevObject是通过pushStack创建的,通过end跟踪链式调用中上一个方法返回的DOM元素集
// end相当与一个出栈操作,通过end,能够返回到上一个链式调用方法的元素集,如 // $().find('button').click(function(){alert(1)}) // 对find('button')返回的元素操作 // .end().click(function(){alert(2)}) // 返回到find('button')返回的元素,然后操作 end: function() {
return this.prevObject || this.constructor(null);
},
// 内部调用, 引用Array方法
push: push,
sort: deletedIds.sort,
splice: deletedIds.splice
};
 
这里定义了一个重要的方法————jQuery.pushStack;它在find,filter,parent等方法中被频繁使用。通过创建prevObject记录上次链式调用时返回的元素集结果,以此能够实现对链式调用元素集的跟踪,利用jQuery.end来回溯到上一次调用的结果。
 

jQuery 源码分析3: jQuery.fn/ jQuery.prototype的更多相关文章

  1. jQuery源码分析系列

    声明:本文为原创文章,如需转载,请注明来源并保留原文链接Aaron,谢谢! 版本截止到2013.8.24 jQuery官方发布最新的的2.0.3为准 附上每一章的源码注释分析 :https://git ...

  2. [转]jQuery源码分析系列

    文章转自:jQuery源码分析系列-Aaron 版本截止到2013.8.24 jQuery官方发布最新的的2.0.3为准 附上每一章的源码注释分析 :https://github.com/JsAaro ...

  3. jQuery源码分析系列(转载来源Aaron.)

    声明:非本文原创文章,转载来源原文链接Aaron. 版本截止到2013.8.24 jQuery官方发布最新的的2.0.3为准 附上每一章的源码注释分析 :https://github.com/JsAa ...

  4. jQuery源码分析系列——来自Aaron

    jQuery源码分析系列——来自Aaron 转载地址:http://www.cnblogs.com/aaronjs/p/3279314.html 版本截止到2013.8.24 jQuery官方发布最新 ...

  5. jQuery 源码分析 8: 回头看jQuery的构造器(jQuery.fn,jQury.prototype,jQuery.fn.init.prototype的分析)

    在第一篇jQuery源码分析中,简单分析了jQuery对象的构造过程,里面提到了jQuery.fn.jQuery.prototype.jQuery.fn.init.prototype的关系. 从代码中 ...

  6. jQuery 源码分析(十七) 事件系统模块 实例方法和便捷方法 详解

    实例方法和便捷方法是指jQuery可以直接通过链接操作的方法,是通过调用$.event上的方法(上一节介绍的底层方法)来实现的,常用的如下: on(types,selector,data,fn,one ...

  7. jQuery 源码分析(十三) 数据操作模块 DOM属性 详解

    jQuery的属性操作模块总共有4个部分,本篇说一下第2个部分:DOM属性部分,用于修改DOM元素的属性的(属性和特性是不一样的,一般将property翻译为属性,attribute翻译为特性) DO ...

  8. [转] jQuery源码分析-如何做jQuery源码分析

    jQuery源码分析系列(持续更新) jQuery的源码有些晦涩难懂,本文分享一些我看源码的方法,每一个模块我基本按照这样的顺序去学习. 当我读到难度的书或者源码时,会和<如何阅读一本书> ...

  9. jquery源码分析之一前言篇

    1.问:jquery源码分析的版本是什么? 答:v3.2.1 2.问:为什么要分析jquery源码? 答:javascript是一切js框架的基础,jquery.es6.vue.angular.rea ...

  10. jQuery源码分析-each函数

    本文部分截取自且行且思 jQuery.each方法用于遍历一个数组或对象,并对当前遍历的元素进行处理,在jQuery使用的频率非常大,下面就这个函数做了详细讲解: 复制代码代码 /*! * jQuer ...

随机推荐

  1. eclipse中 将java项目转换为web项目 博客分类: Tomcat

      1.找到项目工作空间目录,打开.project文件,并修改文件, 修改如下:      找到:<natures> </natures>代码段,在代码段中加入如下内容并保存: ...

  2. bzoj 3926 [Zjoi2015]诸神眷顾的幻想乡(SAM)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3926   [题意]   给定一棵树,每个节点都有相应的颜色,且保证叶子数不超过20,问 ...

  3. ARM Linux字符设备驱动程序

    1.主设备号和次设备号(二者一起为设备号): 一个字符设备或块设备都有一个主设备号和一个次设备号.主设备号用来标识与设备文件相连的驱动程序,用来反  映设备类型.次设备号被驱动程序用来辨别操作的是哪个 ...

  4. Git简介:

    Git中文文档 1.详解在Visual Studio中使用git版本系统(图文) 2.GitExtensions下载地址:http://gitextensions.codeplex.com/ 3.Gi ...

  5. C#- Winform最小化到托盘

    实现前先拉一个notifyIcon控件,在Icon属性中加入一个ICON小图标,然后具体的代码实现如下: using System; using System.Collections.Generic; ...

  6. GPUImage的简单使用

    GPUImage 是一个开源的图像处理库,提供了非常多的滤镜效果来加工图片.GPUImage 并不像一般的第三方库可以直接拖入到工程中使用,而是需要先在本地编译,然后将编译后的文件拖入到工程中使用.配 ...

  7. SpringMVC学习系列 之 表单标签

    http://www.cnblogs.com/liukemng/p/3754211.html 本篇我们来学习Spring MVC表单标签的使用,借助于Spring MVC提供的表单标签可以让我们在视图 ...

  8. android 数据库的升级与降级解决方案

    在我们写的程序中不避免的需要升级.或者说需要改变业务逻辑,那这个时候就需要修改数据库的字段,来适应不同的表结构 我们一般写数据库都是操作一个继承至 SQLiteOpenHelper 的类 然后我们需要 ...

  9. 找出数组前N大的数

    这个题也是个比较有名的面试题.当然有很多变种. 题目意思基本是:从一个数据量很大的数组里找前N大的元素.不允许排序. 这个题有两个比较好的思路: 思路一:用快速排序的思想,是思想,不是要排序; 思路二 ...

  10. Redis作者谈Redis应用场景

    Redis作者谈Redis应用场景 毫无疑问,Redis开创了一种新的数据存储思路,使用Redis,我们不用在面对功能单调的数据库时,把精力放在如何把大象放进冰箱这样的问题上,而是利用Redis灵活多 ...