// 涉及外部代码行:48——70
var arr = [];
var document = window.document;
var getProto = Object.getPrototypeOf;
var slice = arr.slice;
var concat = arr.concat;
var push = arr.push;
var indexOf = arr.indexOf;
var class2type = {};
var toString = class2type.toString;
var hasOwn = class2type.hasOwnProperty;
var fnToString = hasOwn.toString;
var ObjectFunctionString = fnToString.call(Object);
// 代码行:146——255
// 主要代码
jQuery.fn = jQuery.prototype = {
// The current version of jQuery being used
// jquery表示正在使用的jQuery版本号
jquery: version,
// constructor指向构造函数jQuery()。
constructor: jQuery,
// The default length of a jQuery object is 0
// length表示当前jQuery对象中元素的个数。
length: 0,
// .toArray(),将当前jQuery对象转换为真正的数组,转换后的数组包含了所有的元素
toArray: function () {
return slice.call(this);
// 连同slice()一起声明的还有concat()、push()、indexOf()、toString()、hasOwn()、fnToSting()、objectFunctionSting()这些方法。这里通过声明这些核心方法的引用,使的在jQuery代码中可以借用这些核心方法的功能,执行时可通过方法call()和apply()指定方法执行的环境,即关键字this所引用的对象。
},
// Get the Nth element in the matched element set OR
// Get the whole matched element set as a clean array
// get([index]),返回当前jQuery对象中指定位置的元素或包含了全部元素的数组。
get: function (num) {
// Return all the elements in a clean array
//如果没有传入参数,则返回包含了所有元素的新数组。
if (num == null) {
return slice.call(this);
}
// Return just the one element from the set
// 如果制定了参数index,则返回一个单独的元素;参数index从0开始计算,并且支持负数,负数表示从元素集合末尾开始计算。
return num < 0 ? this[num + this.length] : this[num];
},
// Take an array of elements and push it onto the stack
// (returning the new matched element set)
// 创建一个新的空jQuery对象,然后把DOM元素集合放入这个jQuery对象中,并保留对当前jQuery对象的引用。
// 原型方法pushStack()是核心方法之一,它为以下方法提供支持
// DOM遍历:parent()、parents()、parentsUntil()、next()、prev()、nextAll()、prevAll()、nextUntil()、prevUntil()、siblings()、children()、contents()
// jQuery 对象遍历:map()、slice()、first()、last()、eq()
// DOM插入:jQuery.append(),jQuery.prepend(),jQuery.before(),jQuery.after(),jQuery.replaceWith()
// DOM查找、过滤:find()、not()、filter()、closest()、add()、andSelf()
pushStack: function (elems) {
// 参数elems:将放入新jQuery对象的元素数组(或类数组对象)
// Build a new jQuery matched element set
// 构造一个新的空jQuery对象ret,this.constructor指向构造函数函数jQuery,并把参数elems合并到jQuery对象ret中。
var ret = jQuery.merge(this.constructor(), elems);
// Add the old object onto the stack (as a reference)
// 在新的jQuery对象ret上设置属性prevObject,指向当前jQuery对象,从而形成一个链式栈。因此,方法.pushStack()的行为还可以理解为,构建一个新的jQuery对象并入栈,新对象位于栈顶,这也是该方法如此命名的原因所在。
ret.prevObject = this;
// Return the newly-formed element set
// 最后返回新jQuery对象ret。
return ret;
},
// Execute a callback for every element in the matched set.
// 方法.each()遍历当前jQuery对象,并在每个元素上执行回调函数。每当回调函数执行时,会传递当前循环次数作为参考,循环次数从0开始计数;更重要的是,回调函数是在当前元素为上下文的语境中触发的,即关键字this总是指向当前元素;在回调函数中返回false可以终止遍历。
each: function (callback) {
return jQuery.each(this, callback);
},
// .map()遍历当前jQuery对象,在每个元素上执行回调函数,并将回调函数的返回值放入一个新jQuery对象中。该方法常用于获取或设置DOM元素集合的值。
map: function (callback) {
// 执行回调函数时,关键字this指向当前元素。回调函数可以返回一个独立的数据项或数据项数组,返回值将被插入结果集中;如果返回一个数组,数组中的元素会被插入结果集;如果回调函数返回null或undefined,则不会插入任何元素。
return this.pushStack(jQuery.map(this, function (elem, i) {
return callback.call(elem, i, elem);
}));
},
// .slice(start,[end])将匹配元素集合缩减为指定范围的子集;
slice: function () {
return this.pushStack(slice.apply(this, arguments));
},
// .first()将匹配的集合缩减为集合中的第一个元素;
first: function () {
return this.eq(0);
},
// .last()将匹配的集合缩减为集合中的最后一个元素;
last: function () {
return this.eq(-1);
},
// .eq(index)将匹配元素集合缩减为集合中指定位置的元素;
eq: function (i) {
var len = this.length,
j = +i + (i < 0 ? len : 0);
return this.pushStack(j >= 0 && j < len ? [this[j]] : []);
},
// 方法.end()结束当前链条中最近的筛选操作,并将匹配元素集合还原为之前的状态。
end: function () {
// 返回前一个jQuery对象。如果属性prevObject不存在,则构建一个空的jQuery对象返回。
// 方法.pushStack()用于入栈。方法.end()则用于出栈。
return this.prevObject || this.constructor();
},
// For internal use only.
// Behaves like an Array's method, not like a jQuery method.
// 方法.push(value,...)向当前jQuery对象的末尾添加新元素,并返回新长度。
// 方法.sort([orderfunc])对当前jQuery对象中的元素进行排序,可以传入一个比较函数来指定排序方式。
// 方法.splice(start,deleteCount,value,...)向对前jQuery对象中插入、删除或替换元素。
push: push,
sort: arr.sort,
splice: arr.splice
};