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

 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. storm出现的背景

     storm出现的背景 互联网从诞生的第一时间起,对世界的最大改变就是让信息能够实时交互,从而大大加速了各个环节的效率.正因为大家有对信息实时响应.实时交互的需求,所以软件行业除了个人操作系统之外,数 ...

  2. 一切皆WEB

    所有应用都应该成为Web应用吗?当然不是.总有一些重要的例外,有些种类的软件跟网络也毫无关系.但是,这些是少数情况,是一些特殊应用.它们固然是重要的小生态环境,但不管怎么说,就只是“小生态”. 如果你 ...

  3. android 获取当前版本号/修改自定义的应用程序的版本号

    1.获取当前版本号 PackageManager pm = getPackageManager(); PackageInfo pi = pm.getPackageInfo(getPackageName ...

  4. 【python自动化第十篇:】

    复习: 线程与进程的区别: 进程:资源的集合 线程:最小调度单位 进程至少包含一个线程 线程之间的内存是共享的,两个线程操作同一个数据就会修改整个结果(需要mutex加锁来保持数据的一致性),递归锁, ...

  5. Cactus借助Jetty测试Servlet

    这是一个WebProject,但不需要web.xml,因为用不到它 首先是待测试的LoginServlet.java package com.jadyer.servlet; import java.i ...

  6. poj1556

    计算几何+最短路 最短路是套的模版..= = 毕竟不是自己写的..模版上的点竟然是从0开始的. 难在建图.图中,比如2和12点,其间如果没有任何线段阻挡,那么边权是他们的直线距离,如果有线段阻挡,边权 ...

  7. time_t和struct tm之间的转换

    time_t到struct tm的转换: #include <time.h> struct tm *localtime(const time_t *timep); struct tm到ti ...

  8. UVa 497 - Strategic Defense Initiative

    题目:最大上升子序列.输出一组解. 分析:dp,LIS.数据较小 O(n^2)算法就可以. 设以第i个数字作为最大上升子序列中的最后一个数的长度为 f(i),则有转移方程: f(i)= max(f(j ...

  9. java和c#md5加密不同

    java的mad5加密后为32位字符串,c#直接加密后可能不是32位,位数也不确定. 普通的写法 public static string Md5(string sourcein) { var md5 ...

  10. 表单中Readonly和Disabled的区别(转)

    今天做form提交的时候,用到了disabled,form提交的时候怎么获取都是null,后来用hidden解决了这个问题,但是考虑到为什么,最后找到了原因,转载一篇文章,说明一下 原文:http:/ ...