|
|
|
@ -106,77 +106,92 @@
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 获取jQuery对象中的第N个元素,或者获取所有元素组成的数组
|
|
|
|
|
// 定义一个名为`get`的函数,它是`jQuery.fn`(也就是`jQuery`实例的原型对象)上的方法,用于获取`jQuery`对象中的元素。
|
|
|
|
|
// 参数`num`表示要获取元素的索引位置。
|
|
|
|
|
get: function( num ) {
|
|
|
|
|
return num != null ?
|
|
|
|
|
|
|
|
|
|
// 返回指定位置的元素
|
|
|
|
|
( num < 0 ? this[ num + this.length ] : this[ num ] ) :
|
|
|
|
|
|
|
|
|
|
// 返回所有元素组成的数组
|
|
|
|
|
// 如果传入的`num`不为`null`,说明指定了要获取元素的具体位置。
|
|
|
|
|
return num!= null?
|
|
|
|
|
// 判断`num`是否小于0,如果小于0,则表示从后往前计数获取元素。
|
|
|
|
|
// 通过`num + this.length`计算出对应的正向索引(因为在JavaScript数组中可以通过负数索引结合长度来从后往前取值),然后从`this`(指代当前`jQuery`对象,它类似一个类数组对象,内部存储着选中的DOM元素等相关信息)中获取对应位置的元素。
|
|
|
|
|
// 如果`num`大于等于0,则直接从`this`中按正常索引获取对应位置的元素。
|
|
|
|
|
( num < 0? this[ num + this.length ] : this[ num ] ) :
|
|
|
|
|
// 如果`num`为`null`,表示要获取所有元素,通过`slice.call(this)`将类数组形式的`this`(当前`jQuery`对象)转换为真正的数组并返回,这样就能获取到所有被选中的元素组成的数组。
|
|
|
|
|
slice.call( this );
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 将一个元素数组推入到当前jQuery对象的栈中,并返回新的jQuery对象
|
|
|
|
|
// `pushStack`方法用于将一个元素数组推入到当前`jQuery`对象的栈中,并返回一个新的`jQuery`对象。
|
|
|
|
|
// 参数`elems`是要推入栈的元素数组(可以是DOM元素数组或者其他符合要求的数据集合)。
|
|
|
|
|
pushStack: function( elems ) {
|
|
|
|
|
|
|
|
|
|
// 创建一个新的jQuery对象
|
|
|
|
|
// 通过`jQuery.merge`方法将当前`jQuery`对象的构造函数(也就是`jQuery`函数本身)创建一个新的`jQuery`对象,并将传入的`elems`元素合并到这个新对象中。
|
|
|
|
|
// 这样新的`jQuery`对象就包含了原有的元素以及新传入的元素,实现了元素栈的推入操作。
|
|
|
|
|
var ret = jQuery.merge( this.constructor(), elems );
|
|
|
|
|
|
|
|
|
|
// 将旧的对象引用添加到新对象的prevObject属性上
|
|
|
|
|
// 将当前`jQuery`对象(也就是调用`pushStack`方法的这个对象)赋值给新对象的`prevObject`属性,方便后续操作可以回溯到之前的`jQuery`对象,比如在链式操作中实现`end`方法的功能(回到上一个操作对象)。
|
|
|
|
|
ret.prevObject = this;
|
|
|
|
|
// 保持上下文的一致性
|
|
|
|
|
// 将当前`jQuery`对象的`context`属性(通常用于表示操作的上下文,比如选择元素时的父元素等相关信息)赋值给新对象,保持上下文的一致性,使得新对象在后续操作中能基于相同的上下文进行处理。
|
|
|
|
|
ret.context = this.context;
|
|
|
|
|
|
|
|
|
|
// 返回新的jQuery对象
|
|
|
|
|
// 返回新创建并经过处理的`jQuery`对象,以便继续进行链式调用等操作。
|
|
|
|
|
return ret;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 对jQuery对象中的每个元素执行一次提供的回调函数
|
|
|
|
|
// `each`方法用于对`jQuery`对象中的每个元素执行一次提供的回调函数。
|
|
|
|
|
// 参数`callback`是一个函数,它会在每个元素上被调用,并且会传入元素的索引和元素本身作为参数。
|
|
|
|
|
each: function( callback ) {
|
|
|
|
|
// 调用`jQuery.each`函数(这里应该是`jQuery`对象上的一个全局的遍历方法,用于处理各种可迭代对象的遍历操作),将当前`jQuery`对象(`this`指代)和传入的回调函数`callback`作为参数传递进去,实现对每个元素执行回调函数的功能,并返回遍历操作的结果(具体结果格式由`jQuery.each`的实现决定,通常是返回调用者自身方便链式调用等)。
|
|
|
|
|
return jQuery.each( this, callback );
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 将jQuery对象中的每个元素通过提供的回调函数映射到一个新数组中,并返回一个新的jQuery对象
|
|
|
|
|
// `map`方法用于将`jQuery`对象中的每个元素通过提供的回调函数映射到一个新数组中,并返回一个新的`jQuery`对象。
|
|
|
|
|
// 参数`callback`是一个函数,用于对每个元素进行转换操作,生成新的值放入新数组中。
|
|
|
|
|
map: function( callback ) {
|
|
|
|
|
// 首先调用`jQuery.map`函数(类似`jQuery.each`,是用于处理映射操作的方法,会对每个元素应用回调函数并收集结果到新数组中),将当前`jQuery`对象(`this`指代)和一个匿名函数作为参数传递进去。
|
|
|
|
|
// 匿名函数内部会调用传入的`callback`函数,并通过`call`方法改变`callback`函数内部的`this`指向为当前元素,同时传入元素的索引`i`和元素本身`elem`作为参数,这样`callback`函数就能根据每个元素进行相应的映射操作,返回新的值。
|
|
|
|
|
// 然后将`jQuery.map`操作返回的新数组作为参数传入`pushStack`方法,创建一个新的`jQuery`对象并将其返回,这个新的`jQuery`对象包含了经过映射后得到的新元素集合,实现了对元素的映射功能并返回新的可操作对象,方便后续链式调用等操作。
|
|
|
|
|
return this.pushStack( jQuery.map( this, function( elem, i ) {
|
|
|
|
|
return callback.call( elem, i, elem );
|
|
|
|
|
}) );
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 返回一个从当前位置开始,包含指定数量元素的新jQuery对象(如果参数是负数,则从末尾开始计数)
|
|
|
|
|
// `slice`方法用于返回一个从当前位置开始,包含指定数量元素的新`jQuery`对象(如果参数是负数,则从末尾开始计数)。
|
|
|
|
|
// 它利用了JavaScript数组的`slice`方法的类似功能来处理`jQuery`对象(`jQuery`对象内部结构类似数组,可以存储多个元素信息)。
|
|
|
|
|
slice: function() {
|
|
|
|
|
// 通过`slice.apply(this, arguments)`调用数组的`slice`方法,将`this`(当前`jQuery`对象,模拟数组的行为)和传入的参数(和原生`slice`方法的参数意义一样,用于指定起始位置和截取长度等)传递进去,实现对`jQuery`对象元素的截取操作,得到一个新的元素数组。
|
|
|
|
|
// 然后将这个新的元素数组作为参数传入`pushStack`方法,创建并返回一个新的`jQuery`对象,这个新对象包含了截取后的元素集合,达到了获取部分元素组成新`jQuery`对象的目的,方便后续操作。
|
|
|
|
|
return this.pushStack( slice.apply( this, arguments ) );
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 获取jQuery对象中的第一个元素
|
|
|
|
|
// `first`方法用于获取`jQuery`对象中的第一个元素,它通过调用`eq`方法并传入索引`0`来实现。
|
|
|
|
|
first: function() {
|
|
|
|
|
return this.eq( 0 );
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 获取jQuery对象中的最后一个元素
|
|
|
|
|
// `last`方法用于获取`jQuery`对象中的最后一个元素,它通过调用`eq`方法并传入索引`-1`来实现,利用了`eq`方法可以从后往前计数获取元素的功能。
|
|
|
|
|
last: function() {
|
|
|
|
|
return this.eq( -1 );
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 获取jQuery对象中指定位置的元素(如果索引是负数,则从末尾开始计数)
|
|
|
|
|
// `eq`方法用于获取`jQuery`对象中指定位置的元素(如果索引是负数,则从末尾开始计数)。
|
|
|
|
|
// 参数`i`表示要获取元素的索引位置。
|
|
|
|
|
eq: function( i ) {
|
|
|
|
|
var len = this.length,
|
|
|
|
|
j = +i + ( i < 0 ? len : 0 );
|
|
|
|
|
return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
|
|
|
|
|
j = +i + ( i < 0? len : 0 );
|
|
|
|
|
// 先根据传入的索引`i`计算出实际对应的正向索引(如果`i`是负数,则结合`this.length`转换为正向索引,方便后续在类似数组的`jQuery`对象中获取元素),得到`j`。
|
|
|
|
|
// 然后判断`j`是否在有效范围内(大于等于0且小于`len`,也就是当前`jQuery`对象的长度范围内),如果是,则将对应位置的元素包装成数组(因为`pushStack`方法接收的是元素数组参数),再通过`pushStack`方法创建并返回一个新的`jQuery`对象,这个新对象只包含指定位置的那个元素。
|
|
|
|
|
// 如果`j`不在有效范围内,则返回一个空数组通过`pushStack`方法创建并返回一个空的`jQuery`对象,表示没有获取到对应元素。
|
|
|
|
|
return this.pushStack( j >= 0 && j < len? [ this[ j ] ] : [] );
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 结束当前操作,返回到上一个jQuery对象(如果有的话)
|
|
|
|
|
// `end`方法用于结束当前操作,返回到上一个`jQuery`对象(如果有的话),通过返回`prevObject`属性(在`pushStack`方法中设置的上一个对象的引用)来实现,如果没有上一个对象,则返回当前`jQuery`对象的构造函数创建的一个新对象(也就是相当于回到初始状态)。
|
|
|
|
|
end: function() {
|
|
|
|
|
return this.prevObject || this.constructor();
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 以下方法是从数组对象中借用来的,用于内部使用
|
|
|
|
|
// 以下这几个方法是从之前定义的`deletedIds`数组对象中借用来的,直接将对应的数组方法赋值给`jQuery`对象的对应属性,用于内部操作中实现类似数组的功能,比如添加元素、排序元素、删除和插入元素等操作,方便在`jQuery`对象内部按照数组的方式进行数据处理(虽然`jQuery`对象本身不是真正的数组,但模拟了很多数组的行为和操作)。
|
|
|
|
|
push: push,
|
|
|
|
|
sort: deletedIds.sort,
|
|
|
|
|
splice: deletedIds.splice
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// jQuery.extend方法用于扩展jQuery对象本身或其原型对象
|
|
|
|
|
// `jQuery.extend`方法用于扩展`jQuery`对象本身或其原型对象(通过`jQuery.fn.extend`也可以扩展原型对象,下面代码会体现),可以用于添加新的属性、方法或者合并对象等操作,实现功能的扩展和代码的复用等目的。
|
|
|
|
|
jQuery.extend = jQuery.fn.extend = function() {
|
|
|
|
|
var src, copyIsArray, copy, name, options, clone,
|
|
|
|
|
target = arguments[ 0 ] || {},
|
|
|
|
@ -184,49 +199,41 @@
|
|
|
|
|
length = arguments.length,
|
|
|
|
|
deep = false;
|
|
|
|
|
|
|
|
|
|
// 处理深度复制的情况
|
|
|
|
|
// 处理深度复制的情况,如果传入的第一个参数是布尔值,说明可能是要指定是否进行深度拷贝操作。
|
|
|
|
|
if ( typeof target === "boolean" ) {
|
|
|
|
|
deep = target;
|
|
|
|
|
|
|
|
|
|
// 跳过布尔值和目标对象
|
|
|
|
|
// 将目标对象设置为第二个参数(跳过布尔值和原本的第一个目标对象),并将索引`i`向后移动一位,准备开始遍历要扩展的对象。
|
|
|
|
|
target = arguments[ i ] || {};
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 如果目标不是对象或函数,则将其转换为对象
|
|
|
|
|
if ( typeof target !== "object" && !jQuery.isFunction( target ) ) {
|
|
|
|
|
// 如果目标对象不是对象类型(比如是基本数据类型)或者不是函数类型,那么将其转换为一个空对象,确保后续扩展操作能正常进行,因为扩展操作通常是针对对象进行的。
|
|
|
|
|
if ( typeof target!== "object" &&!jQuery.isFunction( target ) ) {
|
|
|
|
|
target = {};
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 如果只有一个参数,则扩展jQuery本身
|
|
|
|
|
// 如果传入的参数只有一个(除了前面可能处理的布尔值参数情况外),说明是要扩展`jQuery`对象本身,将目标对象设置为`this`(也就是`jQuery`对象或者其原型对象,根据调用的是`jQuery.extend`还是`jQuery.fn.extend`而定),并将索引`i`减1,使得后续遍历从正确的位置开始(也就是从唯一的那个要扩展的对象开始)。
|
|
|
|
|
if ( i === length ) {
|
|
|
|
|
target = this;
|
|
|
|
|
i--;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 遍历每一个要扩展的对象
|
|
|
|
|
// 开始遍历每一个要扩展的对象(从索引`i`开始,遍历到参数列表末尾),将每个对象的属性和方法合并到目标对象`target`中。
|
|
|
|
|
for ( ; i < length; i++ ) {
|
|
|
|
|
|
|
|
|
|
// 只处理非null/undefined的值
|
|
|
|
|
if ( ( options = arguments[ i ] ) != null ) {
|
|
|
|
|
|
|
|
|
|
// 扩展基础对象
|
|
|
|
|
// 只处理非`null`和非`undefined`的参数对象,忽略那些无效的参数。
|
|
|
|
|
if ( ( options = arguments[ i ] )!= null ) {
|
|
|
|
|
// 遍历当前要扩展的对象(`options`对象)的每一个属性名(`name`),准备将属性值复制到目标对象`target`中。
|
|
|
|
|
for ( name in options ) {
|
|
|
|
|
src = target[ name ];
|
|
|
|
|
copy = options[ name ];
|
|
|
|
|
|
|
|
|
|
// 防止无限循环
|
|
|
|
|
// 如果目标对象和要复制的属性值指向同一个对象(可能出现循环引用等情况),则跳过本次复制操作,防止出现无限循环或者错误的覆盖等问题。
|
|
|
|
|
if ( target === copy ) {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
// 深度复制的逻辑(略)
|
|
|
|
|
|
|
|
|
|
// 深度复制的逻辑(这里省略了具体代码,应该是进一步判断如果是对象或数组等复杂数据类型,进行递归复制等操作,确保深层嵌套的数据也能正确复制和合并)。
|
|
|
|
|
|
|
|
|
|
// Recurse if we're merging plain objects or arrays
|
|
|
|
|
// 定义一个函数,用于扩展对象或合并对象
|
|
|
|
|
// deep 参数指示是否进行深度拷贝
|
|
|
|
|
// copy 是要合并到第一个对象中的对象或数组
|
|
|
|
|
// target 是被扩展的对象
|
|
|
|
|
// 定义一个函数,用于扩展对象或合并对象,`deep`参数指示是否进行深度拷贝,`copy`是要合并到第一个对象中的对象或数组,`target`是被扩展的对象
|
|
|
|
|
var someFunction = function( deep, copy, target ) {
|
|
|
|
|
// 检查是否进行深度拷贝,且copy是一个纯对象或数组
|
|
|
|
|
if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
|
|
|
|
|